:: commit b2becebbf92225f3c383837ba6ef39a261b4540d

mintsuki <mintsuki@protonmail.com> — 2023-10-05 08:42

parents: b2da2d701e

misc: Only allocate memory and modules above 4GiB on 64-bit platforms

diff --git a/common/fs/file.h b/common/fs/file.h
index 155b47df..c1b78b2b 100644
--- a/common/fs/file.h
+++ b/common/fs/file.h
@@ -36,6 +36,8 @@ struct file_handle *fopen(struct volume *part, const char *filename);
 void fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count);
 void fclose(struct file_handle *fd);
 void *freadall(struct file_handle *fd, uint32_t type);
+#if defined (__x86_64__) || defined (__aarch64__) || defined (__riscv64)
 void *freadall_mode(struct file_handle *fd, uint32_t type, bool allow_high_allocs);
+#endif
 
 #endif
diff --git a/common/fs/file.s2.c b/common/fs/file.s2.c
index 68fb354f..f7ce4437 100644
--- a/common/fs/file.s2.c
+++ b/common/fs/file.s2.c
@@ -96,10 +96,12 @@ void fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count) {
 }
 
 void *freadall(struct file_handle *fd, uint32_t type) {
+#if defined (__x86_64__) || defined (__aarch64__) || defined (__riscv64)
     return freadall_mode(fd, type, false);
 }
 
 void *freadall_mode(struct file_handle *fd, uint32_t type, bool allow_high_allocs) {
+#endif
     if (fd->is_memfile) {
         if (fd->readall) {
             return fd->fd;
@@ -108,7 +110,11 @@ void *freadall_mode(struct file_handle *fd, uint32_t type, bool allow_high_alloc
         fd->readall = true;
         return fd->fd;
     } else {
+#if defined (__x86_64__) || defined (__aarch64__) || defined (__riscv64)
         void *ret = ext_mem_alloc_type_aligned_mode(fd->size, type, 4096, allow_high_allocs);
+#else
+        void *ret = ext_mem_alloc_type_aligned(fd->size, type, 4096);
+#endif
         fd->read(fd, ret, 0, fd->size);
         fd->close(fd);
         fd->fd = ret;
diff --git a/common/mm/pmm.h b/common/mm/pmm.h
index 52e24404..4df6b079 100644
--- a/common/mm/pmm.h
+++ b/common/mm/pmm.h
@@ -56,7 +56,9 @@ void pmm_randomise_memory(void);
 void *ext_mem_alloc(size_t count);
 void *ext_mem_alloc_type(size_t count, uint32_t type);
 void *ext_mem_alloc_type_aligned(size_t count, uint32_t type, size_t alignment);
+#if defined (__x86_64__) || defined (__aarch64__) || defined (__riscv64)
 void *ext_mem_alloc_type_aligned_mode(size_t count, uint32_t type, size_t alignment, bool allow_high_allocs);
+#endif
 
 void *conv_mem_alloc(size_t count);
 
diff --git a/common/mm/pmm.s2.c b/common/mm/pmm.s2.c
index 0f4ea051..d1b9d330 100644
--- a/common/mm/pmm.s2.c
+++ b/common/mm/pmm.s2.c
@@ -356,6 +356,27 @@ void init_memmap(void) {
         uint64_t base = entry->PhysicalStart;
         uint64_t length = entry->NumberOfPages * 4096;
 
+#if !defined (__x86_64__) && !defined (__aarch64__) && !defined (__riscv64)
+        // We only manage memory below 4GiB. For anything above that, make it
+        // EFI reclaimable.
+        if (our_type == MEMMAP_USABLE) {
+            if (base + length > 0x100000000) {
+                if (base < 0x100000000) {
+                    memmap[memmap_entries].base = base;
+                    memmap[memmap_entries].length = 0x100000000 - base;
+                    memmap[memmap_entries].type = our_type;
+
+                    base = 0x100000000;
+                    length -= memmap[memmap_entries].length;
+
+                    memmap_entries++;
+                }
+
+                our_type = MEMMAP_EFI_RECLAIMABLE;
+            }
+        }
+#endif
+
         memmap[memmap_entries].base = base;
         memmap[memmap_entries].length = length;
         memmap[memmap_entries].type = our_type;
@@ -547,11 +568,13 @@ void *ext_mem_alloc_type(size_t count, uint32_t type) {
 }
 
 void *ext_mem_alloc_type_aligned(size_t count, uint32_t type, size_t alignment) {
+#if defined (__x86_64__) || defined (__aarch64__) || defined (__riscv64)
     return ext_mem_alloc_type_aligned_mode(count, type, alignment, false);
 }
 
 // Allocate memory top down.
 void *ext_mem_alloc_type_aligned_mode(size_t count, uint32_t type, size_t alignment, bool allow_high_allocs) {
+#endif
     count = ALIGN_UP(count, alignment);
 
     if (allocations_disallowed)
@@ -565,7 +588,11 @@ void *ext_mem_alloc_type_aligned_mode(size_t count, uint32_t type, size_t alignm
         int64_t entry_top  = (int64_t)(memmap[i].base + memmap[i].length);
 
         // Let's make sure the entry is not > 4GiB
-        if (entry_top >= 0x100000000 && !allow_high_allocs) {
+        if (entry_top >= 0x100000000
+#if defined (__x86_64__) || defined (__aarch64__) || defined (__riscv64)
+         && !allow_high_allocs
+#endif
+        ) {
             entry_top = 0x100000000;
             if (entry_base >= entry_top)
                 continue;
diff --git a/common/protos/limine.c b/common/protos/limine.c
index cd89f3de..9c77e200 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -250,7 +250,11 @@ static struct limine_file get_file(struct file_handle *file, char *cmdline) {
 
     ret.path = reported_addr(path);
 
+#if defined (__x86_64__) || defined (__aarch64__) || defined (__riscv64)
     ret.address = reported_addr(freadall_mode(file, MEMMAP_KERNEL_AND_MODULES, true));
+#else
+    ret.address = reported_addr(freadall(file, MEMMAP_KERNEL_AND_MODULES));
+#endif
     ret.size = file->size;
 
     ret.cmdline = reported_addr(cmdline);
tab: 248 wrap: offon