:: commit d5897b62a511078846cf6603d3a5c29f28d48355

Mintsuki <mintsuki@protonmail.com> — 2026-03-20 10:09

parents: dc850a1773

protos/limine: Handle framebuffer page-level overlaps with other memory regions

diff --git a/common/protos/limine.c b/common/protos/limine.c
index 2e59c48c..b6797fee 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -1304,6 +1304,58 @@ FEAT_END
                            MEMMAP_FRAMEBUFFER, 0, false, false, true);
     }
 
+    // Check for page-level overlaps between framebuffer and other memory regions.
+    // The framebuffer is mapped with a different caching type, so overlapping pages
+    // must be resolved.
+    for (size_t i = 0; i < memmap_entries; i++) {
+        if (memmap[i].type != MEMMAP_FRAMEBUFFER) {
+            continue;
+        }
+
+        uint64_t fb_base = memmap[i].base;
+        uint64_t fb_top = fb_base + memmap[i].length;
+        uint64_t fb_aligned_base = ALIGN_DOWN(fb_base, 4096);
+        uint64_t fb_aligned_top = ALIGN_UP(fb_top, 4096);
+
+        // No overshoot means no possible overlap.
+        if (fb_aligned_base == fb_base && fb_aligned_top == fb_top) {
+            continue;
+        }
+
+        for (size_t j = 0; j < memmap_entries; j++) {
+            if (j == i || memmap[j].length == 0) {
+                continue;
+            }
+
+            uint64_t region_base = memmap[j].base;
+            uint64_t region_top = region_base + memmap[j].length;
+
+            // Check if this region overlaps with the framebuffer's page-aligned extent.
+            if (region_top <= fb_aligned_base || region_base >= fb_aligned_top) {
+                continue;
+            }
+
+            // There is a page-level overlap. Only USABLE regions can be trimmed.
+            if (memmap[j].type != MEMMAP_USABLE) {
+                panic(false, "limine: Framebuffer page-level overlap with non-trimmable memory type %x", memmap[j].type);
+            }
+
+            // Trim the usable region to not overlap with the framebuffer's
+            // page-aligned extent.
+            if (region_base < fb_aligned_base && region_top > fb_aligned_base) {
+                // Region extends before the framebuffer - trim end.
+                memmap[j].length = fb_aligned_base - region_base;
+            } else if (region_base < fb_aligned_top && region_top > fb_aligned_top) {
+                // Region extends after the framebuffer - trim start.
+                memmap[j].length = region_top - fb_aligned_top;
+                memmap[j].base = fb_aligned_top;
+            } else {
+                // Region is entirely within the framebuffer's page-aligned extent - zero it.
+                memmap[j].length = 0;
+            }
+        }
+    }
+
     // Framebuffer feature
 FEAT_START
     struct limine_framebuffer_request *framebuffer_request = get_request(LIMINE_FRAMEBUFFER_REQUEST_ID);
tab: 248 wrap: offon