Compare commits

...

4 Commits

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
9 changed files with 100 additions and 15 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

@@ -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)

View File

@@ -63,7 +63,8 @@ def prepare_patches(col, branch, count, start, end, ignore_binary, signoff,
branch, start, to_do, ignore_binary, series, signoff)
# Fix up the patch files to our liking, and insert the cover letter
patchstream.fix_patches(series, patch_files, keep_change_id)
patchstream.fix_patches(series, patch_files, keep_change_id,
insert_base_commit=not cover_fname)
if cover_fname and series.get('cover'):
patchstream.insert_cover_letter(cover_fname, series, to_do)
return series, cover_fname, patch_files

View File

@@ -357,6 +357,31 @@ Changes in v2:
expected = expected.splitlines()
self.assertEqual(expected, lines[start:(start+len(expected))])
def test_base_commit(self):
"""Test adding a base commit with no cover letter"""
orig_text = self._get_text('test01.txt')
pos = orig_text.index('commit 5ab48490f03051875ab13d288a4bf32b507d76fd')
text = orig_text[:pos]
series = patchstream.get_metadata_for_test(text)
series.base_commit = Commit('1a44532')
series.branch = 'mybranch'
cover_fname, args = self._create_patches_for_test(series)
self.assertFalse(cover_fname)
with capture_sys_output() as out:
patchstream.fix_patches(series, args, insert_base_commit=True)
self.assertEqual('Cleaned 1 patch\n', out[0].getvalue())
lines = tools.read_file(args[0], binary=False).splitlines()
pos = lines.index('-- ')
# We expect these lines at the end:
# -- (with trailing space)
# 2.7.4
# (empty)
# base-commit: xxx
# branch: xxx
self.assertEqual('base-commit: 1a44532', lines[pos + 3])
self.assertEqual('branch: mybranch', lines[pos + 4])
def make_commit_with_file(self, subject, body, fname, text):
"""Create a file and add it to the git repo with a new commit
@@ -527,6 +552,11 @@ complicated as possible''')
self.assertEqual(f'base-commit: {base}', lines[0])
self.assertEqual('branch: second', lines[1])
# Make sure that the base-commit is not present when it is in the
# cover letter
for fname in patch_files:
self.assertNotIn(b'base-commit:', tools.read_file(fname))
# Check that it can skip patches at the end
with capture_sys_output() as _:
_, cover_fname, patch_files = control.prepare_patches(

View File

@@ -76,8 +76,13 @@ class PatchStream:
are interested in. We can also process a patch file in order to remove
unwanted tags or inject additional ones. These correspond to the two
phases of processing.
Args:
keep_change_id (bool): Keep the Change-Id tag
insert_base_commit (bool): True to add the base commit to the end
"""
def __init__(self, series, is_log=False, keep_change_id=False):
def __init__(self, series, is_log=False, keep_change_id=False,
insert_base_commit=False):
self.skip_blank = False # True to skip a single blank line
self.found_test = False # Found a TEST= line
self.lines_after_test = 0 # Number of lines found after TEST=
@@ -103,6 +108,7 @@ class PatchStream:
self.recent_quoted = collections.deque([], 5)
self.recent_unquoted = queue.Queue()
self.was_quoted = None
self.insert_base_commit = insert_base_commit
@staticmethod
def process_text(text, is_comment=False):
@@ -658,6 +664,13 @@ class PatchStream:
outfd.write(line + '\n')
self.blank_count = 0
self.finalise()
if self.insert_base_commit:
if self.series.base_commit:
print(f'base-commit: {self.series.base_commit.hash}',
file=outfd)
if self.series.branch:
print(f'branch: {self.series.branch}', file=outfd)
def insert_tags(msg, tags_to_emit):
"""Add extra tags to a commit message
@@ -778,7 +791,8 @@ def get_metadata_for_test(text):
pst.finalise()
return series
def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False):
def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False,
insert_base_commit=False):
"""Fix up a patch file, by adding/removing as required.
We remove our tags from the patch file, insert changes lists, etc.
@@ -792,6 +806,7 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False):
series (Series): Series information about this patch set
cmt (Commit): Commit object for this patch file
keep_change_id (bool): Keep the Change-Id tag.
insert_base_commit (bool): True to add the base commit to the end
Return:
list: A list of errors, each str, or [] if all ok.
@@ -799,7 +814,8 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False):
handle, tmpname = tempfile.mkstemp()
outfd = os.fdopen(handle, 'w', encoding='utf-8')
infd = open(fname, 'r', encoding='utf-8')
pst = PatchStream(series, keep_change_id=keep_change_id)
pst = PatchStream(series, keep_change_id=keep_change_id,
insert_base_commit=insert_base_commit)
pst.commit = cmt
pst.process_stream(infd, outfd)
infd.close()
@@ -811,7 +827,7 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False):
shutil.move(tmpname, fname)
return cmt.warn
def fix_patches(series, fnames, keep_change_id=False):
def fix_patches(series, fnames, keep_change_id=False, insert_base_commit=False):
"""Fix up a list of patches identified by filenames
The patch files are processed in place, and overwritten.
@@ -820,6 +836,7 @@ def fix_patches(series, fnames, keep_change_id=False):
series (Series): The Series object
fnames (:type: list of str): List of patch files to process
keep_change_id (bool): Keep the Change-Id tag.
insert_base_commit (bool): True to add the base commit to the end
"""
# Current workflow creates patches, so we shouldn't need a backup
backup_dir = None #tempfile.mkdtemp('clean-patch')
@@ -829,7 +846,8 @@ def fix_patches(series, fnames, keep_change_id=False):
cmt.patch = fname
cmt.count = count
result = fix_patch(backup_dir, fname, series, cmt,
keep_change_id=keep_change_id)
keep_change_id=keep_change_id,
insert_base_commit=insert_base_commit)
if result:
print('%d warning%s for %s:' %
(len(result), 's' if len(result) > 1 else '', fname))