[PATCH 5/6] efi_memory: backfill EFI_CONVENTIONAL_MEMORY
Randolph Sapp
rs at ti.com
Thu Apr 2 19:32:25 CEST 2026
On Thu Apr 2, 2026 at 3:53 AM CDT, Ilias Apalodimas wrote:
> Hi Randolph
>
> On Thu, 2 Apr 2026 at 03:14, <rs at ti.com> wrote:
>>
>> From: Randolph Sapp <rs at ti.com>
>>
>> Backfill any fragmented EFI_CONVENTIONAL_MEMORY when LMB allocations
>> start to fail. This may be a low memory environment, or maybe LMB is
>> running up against a tricky reserved region.
>>
>> Signed-off-by: Randolph Sapp <rs at ti.com>
>> ---
>> lib/efi_loader/efi_memory.c | 35 +++++++++++++++++++++++++++++++++--
>> 1 file changed, 33 insertions(+), 2 deletions(-)
>>
>> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
>> index 882366a9f8a..f07cc39b157 100644
>> --- a/lib/efi_loader/efi_memory.c
>> +++ b/lib/efi_loader/efi_memory.c
>> @@ -441,6 +441,27 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated)
>> return EFI_NOT_FOUND;
>> }
>>
>> +/**
>> + * efi_get_conventional_start - find the highest conventional region start
>> + * address with at least the specified number of
>> + * pages
>> + *
>> + * @pages: number of pages required to be in that carveout
>> + * Return: starting address of the give carveout
>> + */
>> +static u64 efi_get_conventional_start(u64 pages)
>> +{
>> + struct efi_mem_list *item;
>> +
>> + list_for_each_entry(item, &efi_mem, link) {
>> + if (item->desc.type != EFI_CONVENTIONAL_MEMORY)
>> + continue;
>> + if (item->desc.num_pages >= pages)
>> + return item->desc.physical_start;
>> + }
>> + return 0;
>
> We've been bitten by this in the past and although unlikely 0 is a
> valid address for some hardware. Can we return something different if
> we don't find a match? UINT64_MAX perhaps?
>
>> +}
>> +
>> /**
>> * efi_allocate_pages - allocate memory pages
>> *
>> @@ -507,10 +528,20 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
>> /* Reserve that map in our memory maps */
>> ret = efi_update_memory_map(efi_addr, pages, memory_type, true, false);
>
> In theory the lmb and the EFI maps are in sync. I haven't checked
> close enough yet, but do you have cases where lmb_alloc worked and
> updating the efi memory map failed?
Fair point. Now that I've fixed the FDT warning I should probably check if I can
actually reproduce the issue that actually required this.
>> if (ret != EFI_SUCCESS) {
>> - /* Map would overlap, bail out */
>> + /* Map would overlap, try something else */
>> lmb_free(addr, (u64)pages << EFI_PAGE_SHIFT, flags);
>> unmap_sysmem((void *)(uintptr_t)efi_addr);
>> - return EFI_OUT_OF_RESOURCES;
>> +
>> + /* See if there is any EFI_CONVENTIONAL_MEMORY allocations */
>> + if (type != EFI_ALLOCATE_ADDRESS) {
>
> Can you please inverse this. It's going to reduce the identation.
> if (type == EFI_ALLOCATE_ADDRESS)
>> + *memory = efi_get_conventional_start(pages);
>> + if (*memory != 0)
>
> Same here
>
>> + return efi_allocate_pages(EFI_ALLOCATE_ADDRESS,
>> + memory_type, pages,
>> + memory);
>> + }
>> +
>> + return EFI_OUT_OF_RESOURCES;
>> }
>>
>> *memory = efi_addr;
>> --
>> 2.53.0
>>
>
> Thanks
> /Ilias
More information about the U-Boot
mailing list