:: commit 9b73cfa033d97a39fd770eca84c941917e6346bf

mintsuki <mintsuki@protonmail.com> — 2022-07-26 17:55

parents: ae9ccdde12

pmm: Reclaim bootservices entries last and disallow allocations after

diff --git a/common/mm/pmm.s2.c b/common/mm/pmm.s2.c
index 1ecf2eef..2d73b033 100644
--- a/common/mm/pmm.s2.c
+++ b/common/mm/pmm.s2.c
@@ -474,42 +474,6 @@ fail:
 static void pmm_reclaim_uefi_mem(struct e820_entry_t *m, size_t *_count) {
     size_t count = *_count;
 
-    // First, ensure the boot services are still boot services, or free, in
-    // the EFI memmap
-    for (size_t i = 0; i < count; i++) {
-        if (m[i].type != MEMMAP_EFI_BOOTSERVICES)
-            continue;
-
-        // Go through EFI memmap and ensure this entry fits within a boot services
-        // or conventional entry
-        size_t entry_count = efi_mmap_size / efi_desc_size;
-
-        for (size_t j = 0; j < entry_count; j++) {
-            EFI_MEMORY_DESCRIPTOR *entry = (void *)efi_mmap + j * efi_desc_size;
-
-            switch (entry->Type) {
-                case EfiBootServicesCode:
-                case EfiBootServicesData:
-                case EfiConventionalMemory:
-                    break;
-                default:
-                    continue;
-            }
-
-            uintptr_t base = m[i].base;
-            uintptr_t top = base + m[i].length;
-            uintptr_t efi_base = entry->PhysicalStart;
-            uintptr_t efi_size = entry->NumberOfPages * 4096;
-            uintptr_t efi_top = efi_base + efi_size;
-
-            if (!(base >= efi_base && base <  efi_top
-               && top  >  efi_base && top  <= efi_top))
-                continue;
-
-            m[i].type = MEMMAP_USABLE;
-        }
-    }
-
     size_t recl_i = 0;
 
     for (size_t i = 0; i < count; i++) {
@@ -600,6 +564,45 @@ another_recl:;
         goto another_recl;
     }
 
+    // Ensure the boot services are still boot services, or free, in
+    // the EFI memmap, and disallow allocations since our stack and page tables
+    // are placed in this newly freed memory.
+    for (size_t i = 0; i < count; i++) {
+        if (m[i].type != MEMMAP_EFI_BOOTSERVICES)
+            continue;
+
+        // Go through EFI memmap and ensure this entry fits within a boot services
+        // or conventional entry
+        size_t entry_count = efi_mmap_size / efi_desc_size;
+
+        for (size_t j = 0; j < entry_count; j++) {
+            EFI_MEMORY_DESCRIPTOR *entry = (void *)efi_mmap + j * efi_desc_size;
+
+            switch (entry->Type) {
+                case EfiBootServicesCode:
+                case EfiBootServicesData:
+                case EfiConventionalMemory:
+                    break;
+                default:
+                    continue;
+            }
+
+            uintptr_t base = m[i].base;
+            uintptr_t top = base + m[i].length;
+            uintptr_t efi_base = entry->PhysicalStart;
+            uintptr_t efi_size = entry->NumberOfPages * 4096;
+            uintptr_t efi_top = efi_base + efi_size;
+
+            if (!(base >= efi_base && base <  efi_top
+               && top  >  efi_base && top  <= efi_top))
+                continue;
+
+            m[i].type = MEMMAP_USABLE;
+        }
+    }
+
+    allocations_disallowed = true;
+
     sanitise_entries(m, &count, false);
 
     *_count = count;
tab: 248 wrap: offon