Compare commits

..

4 Commits
tpm ... eth

Author SHA1 Message Date
Simon Glass
11a7a0ae1c efi_loader: Move device-removal later in exit-boot-services
This removal should be the last thing done, so that U-Boot does no more
memory allocations afterwards. Move it and add a comment.

Note that the TCG2 log is updated after this call, but I cannot see any
allocations there.

Series-to: u-boot
Series-cc: trini, heinrich, ilias
Series-cc: neil.armstrong@linaro.org
Reported-by: Christian Kohlschütter <christian@kohlschutter.com>

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-04-06 10:12:41 +12:00
Simon Glass
bde070d220 designware: Use the remove() method with related drivers
Several drivers make use of the designware Ethernet driver but do not
implement the remove() method. Add this so that DMA is stopped when the
OS is booted to avoid memory corruption, etc.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Christian Kohlschütter <christian@kohlschutter.com>
2025-04-06 10:12:41 +12:00
Simon Glass
63c09ba342 net: designware: Disable DMA on removal
At present, removing the device frees struct dw_eth_dev but does not
disable DMA. When DMA is active, packets can be received even if the
driver is not active.

While it is possible that the memory used by the struct may remain
untouched after removal, any other allocation may reuse that memory
and result in DMA writing to random addresses.

In most case U-Boot does this removal in announce_and_cleanup()
immediately before jumping to the OS. No further allocations are done
after that point.

But with EFI_LOADER this function is not called before jumping to the
EFI app. U-Boot continues to run while GRUB starts and finishes, as well
as while Linux is starting up. During this time, devices cannot be
removed, as they are in use. U-Boot completes the removal when
efi_exit_boot_services() is called. It seems that this function does
more allocations after calling dm_remove_devices_active() although I
can't figure out where.

Fix this by disabling DMA when the driver is removed.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Christian Kohlschütter <christian@kohlschutter.com>
2025-04-06 10:12:41 +12:00
Simon Glass
bcfa94be95 patman: Show base commit on each patch when no cover letter
If a series is sent without a cover letter, there is no indication of
the base commit. Add support for this, since single patches of small
series may not always have a cover letter.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-04-06 10:12:41 +12:00
7 changed files with 45 additions and 13 deletions

View File

@@ -805,10 +805,11 @@ clk_err:
return err;
}
static int designware_eth_remove(struct udevice *dev)
int designware_eth_remove(struct udevice *dev)
{
struct dw_eth_dev *priv = dev_get_priv(dev);
_dw_eth_halt(priv);
free(priv->phydev);
mdio_unregister(priv->bus);
mdio_free(priv->bus);

View File

@@ -247,6 +247,18 @@ struct dw_eth_dev {
int designware_eth_of_to_plat(struct udevice *dev);
int designware_eth_probe(struct udevice *dev);
/**
* designware_eth_remove() - Remove the device
*
* Disables DMA and marks the device as remove. This must be called before
* booting an OS, to ensure that DMA is inactive.
*
* @dev: Device to remove
* Return 0 if OK, -ve on error
*/
int designware_eth_remove(struct udevice *dev);
extern const struct eth_ops designware_eth_ops;
struct dw_eth_pdata {

View File

@@ -145,6 +145,11 @@ static int dwmac_meson8b_probe(struct udevice *dev)
return designware_eth_probe(dev);
}
static int dwmac_meson8b_remove(struct udevice *dev)
{
return designware_eth_remove(dev);
}
static const struct udevice_id dwmac_meson8b_ids[] = {
{ .compatible = "amlogic,meson-gxbb-dwmac", .data = (ulong)dwmac_setup_gx },
{ .compatible = "amlogic,meson-g12a-dwmac", .data = (ulong)dwmac_setup_axg },
@@ -158,6 +163,7 @@ U_BOOT_DRIVER(dwmac_meson8b) = {
.of_match = dwmac_meson8b_ids,
.of_to_plat = dwmac_meson8b_of_to_plat,
.probe = dwmac_meson8b_probe,
.remove = dwmac_meson8b_remove,
.ops = &designware_eth_ops,
.priv_auto = sizeof(struct dw_eth_dev),
.plat_auto = sizeof(struct dwmac_meson8b_plat),

View File

@@ -44,6 +44,11 @@ static int dwmac_s700_probe(struct udevice *dev)
return designware_eth_probe(dev);
}
static int dwmac_s700_remove(struct udevice *dev)
{
return designware_eth_remove(dev);
}
static int dwmac_s700_of_to_plat(struct udevice *dev)
{
return designware_eth_of_to_plat(dev);
@@ -60,6 +65,7 @@ U_BOOT_DRIVER(dwmac_s700) = {
.of_match = dwmac_s700_ids,
.of_to_plat = dwmac_s700_of_to_plat,
.probe = dwmac_s700_probe,
.remove = dwmac_s700_remove,
.ops = &designware_eth_ops,
.priv_auto = sizeof(struct dw_eth_dev),
.plat_auto = sizeof(struct eth_pdata),

View File

@@ -130,6 +130,11 @@ static int dwmac_socfpga_probe(struct udevice *dev)
return designware_eth_probe(dev);
}
static int dwmac_socfpga_remove(struct udevice *dev)
{
return designware_eth_remove(dev);
}
static const struct udevice_id dwmac_socfpga_ids[] = {
{ .compatible = "altr,socfpga-stmmac" },
{ }
@@ -141,6 +146,7 @@ U_BOOT_DRIVER(dwmac_socfpga) = {
.of_match = dwmac_socfpga_ids,
.of_to_plat = dwmac_socfpga_of_to_plat,
.probe = dwmac_socfpga_probe,
.remove = dwmac_socfpga_remove,
.ops = &designware_eth_ops,
.priv_auto = sizeof(struct dw_eth_dev),
.plat_auto = sizeof(struct dwmac_socfpga_plat),

View File

@@ -737,13 +737,9 @@ static int cr50_i2c_report_state(struct udevice *dev, char *str, int str_max)
static int cr50_i2c_open(struct udevice *dev)
{
struct cr50_priv *priv = dev_get_priv(dev);
char buf[80];
int ret;
if (priv->locality != -1)
return -EBUSY;
ret = process_reset(dev);
if (ret)
return log_msg_ret("reset", ret);

View File

@@ -2250,14 +2250,6 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
list_del(&evt->link);
}
if (!efi_st_keep_devices) {
bootm_disable_interrupts();
if (IS_ENABLED(CONFIG_USB_DEVICE))
udc_disconnect();
board_quiesce_devices();
dm_remove_devices_active();
}
/* Patch out unsupported runtime function */
efi_runtime_detach();
@@ -2279,6 +2271,19 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
/* Give the payload some time to boot */
efi_set_watchdog(0);
schedule();
/*
* this should be the last thing done, to avoid memory allocations
* between removing devices and the OS taking over
*/
if (!efi_st_keep_devices) {
bootm_disable_interrupts();
if (IS_ENABLED(CONFIG_USB_DEVICE))
udc_disconnect();
board_quiesce_devices();
dm_remove_devices_active();
}
out:
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
if (ret != EFI_SUCCESS)