]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: fallback to unrestricted allocation if initrd allocation doesn't fit below...
authorLennart Poettering <lennart@poettering.net>
Wed, 12 Mar 2025 19:14:40 +0000 (20:14 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sat, 22 Mar 2025 15:51:44 +0000 (15:51 +0000)
Fixes: #36706
(cherry picked from commit c5a50467921f615846b3bbe3c3ff592953a6163a)

src/boot/util.h

index af14a0e31e467e1cdfa3a959bed6442b0a68ade2..b22db82ae461ea30a001ef76bf4bf806e90347a1 100644 (file)
@@ -100,26 +100,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);