Hi Qing,
On 2026-10-01T20:44:44, Qing Li <[email protected]> wrote:
> boot: image: skip FDT reservation replay after the fdt step
>
> boot_fdt_add_mem_rsv_regions() removes the ranges described by
> gd->fdt_blob (the U-Boot control device tree) before adding those of
> the new blob. It runs both in the BOOTM_STATE_FDT step and again from
> image_setup_linux() during BOOTM_STATE_OS_PREP.
>
> In a stepped boot (bootm fdt followed by bootm prep) the second call
> still sees gd->fdt_blob pointing at the control device tree, so it
> frees the control tree's ranges a second time. LMB tracks plain ranges,
> not their owner, so this also drops parts of the OS device tree's
> reservations before re-adding them; the re-add then fails with -EEXIST
> for the LMB_NOMAP regions. On Xiaomi crux this lost 128 KiB of the
> XBL/AOP reservation at 0x85f20000-0x85f3ffff.
>
> Only add the reservations when the separate FDT step has not run.
The free pass comes from 623f6c5b6ab7 ("boot: image-fdt: free old dtb
reservations"), so please can you add a Fixes: tag for it?
>
> Signed-off-by: Qing Li <[email protected]>
>
> boot/image-board.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
> diff --git a/boot/image-board.c b/boot/image-board.c
> @@ -918,7 +918,14 @@ int image_setup_linux(struct bootm_headers *images)
> + if (CONFIG_IS_ENABLED(OF_LIBFDT) &&
> + !(images->state & BOOTM_STATE_FDT))
> boot_fdt_add_mem_rsv_regions(*of_flat_tree);
This skips the reservations, but boot_relocate_fdt() a few lines below
still runs a second time in the stepped case. The 'bootm fdt' step has
already relocated the tree and updated images->ft_addr and
images->ft_len, so the prep step allocates another block (with a
second CONFIG_SYS_FDT_PAD) and copies the tree again, and the first
allocation is never freed.
MIPS handles this in boot_reloc_fdt() in arch/mips/lib/bootm.c by
skipping both the reservations and the relocation when BOOTM_STATE_FDT
is set. I suspect the same makes sense here, e.g. work out the
condition once and use it for both calls. What do you think?
Please can you also add a test for this? Sandbox goes through
image_setup_linux() and test/py/tests/test_fit.py already uses 'bootm
prep', so a 'bootm fdt' followed by 'bootm prep' with a check of the
resulting LMB reservations should be enough to catch it.
Regards,
Simon