:: commit 428e94febe31f94040f1d05b09a7b63d604a80e0

Mintsuki <mintsuki@protonmail.com> — 2026-02-17 06:14

parents: f1b89ec1bb

mm/pmm: Prefer allocations below 4GiB on x86

diff --git a/common/mm/pmm.s2.c b/common/mm/pmm.s2.c
index 9030aebe..d793436c 100644
--- a/common/mm/pmm.s2.c
+++ b/common/mm/pmm.s2.c
@@ -635,6 +635,16 @@ void *ext_mem_alloc_type_aligned_mode(uint64_t count, uint32_t type, size_t alig
     if (allocations_disallowed)
         panic(false, "Memory allocations disallowed");
 
+#if defined(__x86_64__) || defined(__i386__)
+    // Try below 4GiB first to avoid relying on firmware identity-mapping
+    // memory above 4GiB (some buggy UEFI implementations don't).
+    uint64_t limit = 0x100000000;
+
+again:
+#else
+    uint64_t limit = UINT64_MAX;
+#endif
+
     for (int i = memmap_entries - 1; i >= 0; i--) {
         if (memmap[i].type != 1)
             continue;
@@ -642,14 +652,11 @@ void *ext_mem_alloc_type_aligned_mode(uint64_t count, uint32_t type, size_t alig
         int64_t entry_base = (int64_t)(memmap[i].base);
         int64_t entry_top  = (int64_t)(memmap[i].base + memmap[i].length);
 
-#if defined(__x86_64__) || defined(__i386__)
-        // Let's make sure the entry is not > 4GiB
-        if (entry_top >= 0x100000000 && !allow_high_allocs) {
-            entry_top = 0x100000000;
+        if ((uint64_t)entry_top > limit) {
+            entry_top = (int64_t)limit;
             if (entry_base >= entry_top)
                 continue;
         }
-#endif
 
         int64_t alloc_base = ALIGN_DOWN(entry_top - (int64_t)count, alignment);
 
@@ -683,6 +690,13 @@ void *ext_mem_alloc_type_aligned_mode(uint64_t count, uint32_t type, size_t alig
         return ret;
     }
 
+#if defined(__x86_64__) || defined(__i386__)
+    if (allow_high_allocs && limit < UINT64_MAX) {
+        limit = UINT64_MAX;
+        goto again;
+    }
+#endif
+
     panic(false, "High memory allocator: Out of memory");
 }
 
tab: 248 wrap: offon