diff --git a/src/boot/util.h b/src/boot/util.h index 2b5cc7213e9..e1d65770d6c 100644 --- a/src/boot/util.h +++ b/src/boot/util.h @@ -103,26 +103,32 @@ static inline Pages xmalloc_pages( } static inline Pages xmalloc_initrd_pages(size_t n_pages) { - /* The original native x86 boot protocol of the Linux kernel was not 64bit safe, hence we allocate - * memory for the initrds below the 4G boundary on x86, since we don't know early enough which - * protocol we'll use to ultimately boot the kernel. This restriction is somewhat obsolete, since - * these days we generally prefer the kernel's newer EFI entrypoint instead, which has no such - * limitations. On other architectures we do not bother with any restriction on this, in particular - * as some of them don't even have RAM mapped to such low addresses. */ + /* The original native x86 boot protocol of the Linux kernel was not 64bit safe, hence we try to + * allocate memory for the initrds below the 4G boundary on x86, since we don't know early enough + * which protocol we'll use to ultimately boot the kernel. This restriction is somewhat obsolete, + * since these days we generally prefer the kernel's newer EFI entrypoint instead, which has no such + * limitations. There's a good chance that for large allocations we won't be successful, hence + * immediately fallback to an unrestricted allocation. On other architectures we do not bother with + * any restriction on this, in particular as some of them don't even have RAM mapped to such low + * addresses. */ #if defined(__i386__) || defined(__x86_64__) - return xmalloc_pages( + EFI_PHYSICAL_ADDRESS addr = UINT32_MAX; /* Below 4G boundary. */ + if (BS->AllocatePages( AllocateMaxAddress, EfiLoaderData, EFI_SIZE_TO_PAGES(n_pages), - UINT32_MAX /* Below 4G boundary. */); -#else + &addr) == EFI_SUCCESS) + return (Pages) { + .addr = addr, + .n_pages = n_pages, + }; +#endif return xmalloc_pages( AllocateAnyPages, EfiLoaderData, EFI_SIZE_TO_PAGES(n_pages), 0 /* Ignored. */); -#endif } void convert_efi_path(char16_t *path);