[PATCH] lmb: Reinstate access to memory above ram_top
Marek Vasut
marek.vasut at mailbox.org
Mon Mar 23 05:16:14 CET 2026
On 3/23/26 12:25 AM, Mark Kettenis wrote:
>> Date: Sun, 22 Mar 2026 22:59:53 +0100
>>
>> On 3/22/26 10:45 PM, Gary Guo wrote:
>>
>> [...]
>>
>>>> Is your malloc area by any chance above the 4 GiB boundary ? Or how come
>>>> does EFI allocate pages from above 4 GiB range? It should not be doing
>>>> that and that is what should be fixed, at least until the DMA32
>>>> allocator is in place.
>>>>
>>>> Please keep in mind, that revering this patch breaks other use cases,
>>>> like loading into the DRAM above 4 GiB.
>
> Well, technically it doesn't break things as this is new
> functionality.
It isn't, this change effectively reverted previous change, so this is
the original behavior.
>>> Code in lib/efi_loader uses efi_allocate_pool (in lib/efi_loader/efi_memory.c)
>>> whenever it allocates, which calls efi_allocate_pages, which calls into
>>> lmb_alloc_mem. There's no malloc here.
>> Does something like this make the issue go away ?
>>
>> "
>> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
>> index b77c2f980cc..44eccc0cf35 100644
>> --- a/lib/efi_loader/efi_memory.c
>> +++ b/lib/efi_loader/efi_memory.c
>> @@ -475,8 +475,10 @@ efi_status_t efi_allocate_pages(enum
>> efi_allocate_type type,
>> flags = LMB_NOOVERWRITE | LMB_NONOTIFY;
>> switch (type) {
>> case EFI_ALLOCATE_ANY_PAGES:
>> + addr = map_to_sysmem((void *)(uintptr_t)0xffff0000);
>> +
>> /* Any page */
>> - err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, EFI_PAGE_SIZE, &addr,
>> + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, EFI_PAGE_SIZE, &addr,
>> len, flags);
>> if (err)
>> return EFI_OUT_OF_RESOURCES;
>> "
>>
>> If so, then maybe we need a temporary config option which limits the
>> EFI_ALLOCATE_ANY_PAGES below 4 GiB on hardware that has DMA limitations.
>
> Note that some arm64 systems (e.g. Apple Silicon) have *no* memory
> below 4 GiB. So that change must indeed be behind a config option and
> care must be taken on what systems to enabled it.
Indeed, good point. I suspect we should call the option something like
"CONFIG_BROKEN_DMA_ABOVE_4G" or "CONFIG_BROKEN_DMA64" , so that once the
DMA32 allocator lands, it can be enabled exactly on those machines and
that option deprecated instead.
> To come back to my earlier statement that some SoCs don't fully
> support DMA above the 4 GiB boundary: I specifically mentioned
> Raspberry Pi and various Rockchip SoCs. I'm sorry I didn't get around
> to testing those boards, but I recently did some work on adding
> support for the RK3576 SoC to OpenBSD and can confirm that its SD
> controller does not support DMA above the 4 GiB boundary. That means
> that with the diff that has now been commited, any attempt to load
> into DRAM above 4 GiB from SD card or MMC is probably going to corrup
> some memory below 4 GiB. The Ethernet controller on those boards does
> support DMA above 4 GiB though.
I also have hardware with such limitations, but please read on ...
> That said, I'd say that on a platform where some of the supported
> storage or network devices don't support DMA above 4 GiB, lmb should
> not make that memory available until bounce buffers are implemented.
I don't think LMB is the right tool, because LMB prevents everyone from
using the memory above 4 GiB boundary, and that makes the memory
effectively useless.
For example, it is currently (with this patch) possible to TFTP or WGET
into the memory above 4 GiB, even if the ethernet MAC does not support
direct writes above 4 GiB boundary, because U-Boot network stack copies
packets from its packet buffer into the target location (at the expense
of slight performance drop).
I think it would be better to identify the few places which may pass
64-bit memory addresses to 32-bit only hardware and fix those up on
affected hardware ... and then start working toward some DMA32 allocator.
More information about the U-Boot
mailing list