Hi Ben On Sun, 9 Mar 2025 at 20:12, Ben Schneider <ben@xxxxxxxxx> wrote: > > Hi Ilias, thank you for connecting the threads. I'm clearly > struggling a bit and appreciate how patient and helpful > everyone has been. No worries, I'd rather help than leave a bug lingering around. They tend to come back biting > > On Saturday, March 8th, 2025 at 5:43 PM, Ilias Apalodimas <ilias.apalodimas@xxxxxxxxxx> wrote: > > The 'efidebug' command will dump the EFI memory map. Can you send that? > > This is what U-Boot reports: > > Type Start End Attributes > ================ ================ ================ ========== > CONVENTIONAL 0000000000000000-0000000004000000 WB > BOOT DATA 0000000004000000-0000000004200000 WB > CONVENTIONAL 0000000004200000-0000000004400000 WB > BOOT DATA 0000000004400000-0000000005400000 WB > CONVENTIONAL 0000000005400000-000000003eabc000 WB > BOOT DATA 000000003eabc000-000000003eac1000 WB > RUNTIME DATA 000000003eac1000-000000003eac2000 WB|RT > BOOT DATA 000000003eac2000-000000003eac3000 WB > RUNTIME DATA 000000003eac3000-000000003eae5000 WB|RT > BOOT DATA 000000003eae5000-000000003eaee000 WB > BOOT CODE 000000003eaee000-000000003fb8a000 WB > RUNTIME DATA 000000003fb8a000-000000003fb8b000 WB|RT > BOOT CODE 000000003fb8b000-000000003ff00000 WB > RUNTIME CODE 000000003ff00000-000000003ff10000 WB|RT > BOOT CODE 000000003ff10000-0000000040000000 WB > > > Any idea if we can reproduce this on QEMU? > > I have not attempted to reproduce with QEMU. > > From what I can tell on my device, total_slots is 467 and > target_slot seems to always start with a value of 0 despite the > comment that it should be a random value in [0, total_slots). > > In the first iteration through the second for loop, > MD_NUM_SLOTS(md) appears to have a value of 24 and since > target_slot is always 0, it never reaches the 'continue' > statement. With current builds, &target appears to have a value of > 3faee138. &target is the stack-allocated address -- it makes sense to be identical. What we really want to print is 'target,' which is the requested address. Can you print 'target' in both of your success/fail cases and also apply the patch below to u-boot: diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 6d00b1862505..421206d3c4a9 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -456,6 +456,9 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, uint flags; efi_status_t ret; phys_addr_t addr; + efi_uintn_t map_size; + struct efi_mem_desc *memmap, *map; + int i; /* Check import parameters */ if (memory_type >= EFI_PERSISTENT_MEMORY_TYPE && @@ -490,6 +493,18 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, if (*memory & EFI_PAGE_MASK) return EFI_NOT_FOUND; + efi_get_memory_map_alloc(&map_size, &memmap); + +#define EFI_PHYS_ADDR_WIDTH (int)(sizeof(efi_physical_addr_t) * 2) + for (i = 0, map = memmap; i < map_size / sizeof(*map); map++, i++) { + printf("%-x %.*llx-%.*llx\n", map->type, EFI_PHYS_ADDR_WIDTH, + (u64)map_to_sysmem((void *)(uintptr_t) map->physical_start), + EFI_PHYS_ADDR_WIDTH, + (u64)map_to_sysmem((void *)(uintptr_t) (map->physical_start + map->num_pages * EFI_PAGE_SIZE))); + } + + efi_free_pool(memmap); + addr = map_to_sysmem((void *)(uintptr_t)*memory); addr = (u64)lmb_alloc_addr(addr, len, flags); if (!addr) That will print the memory map, right before the efi_allocate_pages() request. > U-Boot appears to send this address to map_to_sysmem() > [1] which seems to return 0, which is then what results in the > EFI_NOT_FOUND. map_to_sysmem() does nothing in actual hardware, it's there for an internal platform called 'sandbox'. What fails is the call to efi_allocate_pages(). > > I went back to try figure out why it is somehow working when I > block the 'break' statement with the condition status == > EFI_SUCCESS. Doing so causes the loop to start its second > iteration when EFI_NOT_FOUND comes back. In the second iteration, > MD_NUM_SLOTS(md) is 0 so we reach the 'continue' statement. This > happens for the third and fourth iteration too. On the fifth > iteration, MD_NUM_SLOTS(md) is 443 so it makes its second call to > efi_allocate_pages(). On all iterations, target_slot remains 0. > > What is confusing is this second call to efi_allocate_pages() > seems to have the same value for &target of 3faee138, but this > time when U-Boot calls map_to_sysmem() it returns a value of > 88080384 instead of 0. As a result, we get EFI_SUCCESS and the > kernel boots. Look above, what changes is the physical address not the pointer itself. What I assume is happening here, is that the first call requests an address which U-Boot somehow has already allocated, or the requested length exceeds what we have available. Then you move to the next slot and the new address happens to be ok. > > U-Boot also reports a new reservation in its lmb map between the > first and second calls to efi_allocate_pages(). > Yes internally efi_allocate_pages() uses the lmb APIs to allocate and manage memory so that's normal. > During first call to efi_allocate_pages(): > > lmb_dump_all: > memory.count = 0x1 > memory[0] [0x0-0x3fffffff], 0x40000000 bytes, flags: none > reserved.count = 0x5 > reserved[0] [0x4000000-0x41fffff], 0x200000 bytes, flags: none > reserved[1] [0x4400000-0x53fffff], 0x1000000 bytes, flags: none > reserved[2] [0x3dae3000-0x3e2c8fff], 0x7e6000 bytes, flags: no-overwrite, no-map > reserved[3] [0x3ea6c000-0x3eaedfff], 0x82000 bytes, flags: no-overwrite, no-map > reserved[4] [0x3eaee960-0x3fffffff], 0x15116a0 bytes, flags: no-map > > During second call to efi_allocate_pages(): > > lmb_dump_all: > memory.count = 0x1 > memory[0] [0x0-0x3fffffff], 0x40000000 bytes, flags: none > reserved.count = 0x6 > reserved[0] [0x0-0x113ffff], 0x1140000 bytes, flags: no-overwrite, no-map > reserved[1] [0x4000000-0x41fffff], 0x200000 bytes, flags: none > reserved[2] [0x4400000-0x53fffff], 0x1000000 bytes, flags: none > reserved[3] [0x3dae3000-0x3e2c8fff], 0x7e6000 bytes, flags: no-overwrite, no-map > reserved[4] [0x3ea6c000-0x3eaedfff], 0x82000 bytes, flags: no-overwrite, no-map > reserved[5] [0x3eaee960-0x3fffffff], 0x15116a0 bytes, flags: no-map > > [1] https://github.com/u-boot/u-boot/blob/master/lib/efi_loader/efi_memory.c#L493 > Cheers /Ilias