From f16ede905cb02e9d887f52e2c524cf2ac94e88b3 Mon Sep 17 00:00:00 2001
From: Amelia Coutard <eliottulio.coutard@gmail.com>
Date: Mon, 6 Mar 2023 00:40:35 +0100
Subject: [PATCH] Edited os::paging::setup_pages a bit. Notably, the global bit
 is now set for all hhigher-half memory

---
 kernel/src/kernel.cpp |  4 ++--
 kernel/src/paging.cpp | 22 +++++++++++++---------
 kernel/src/paging.hpp |  2 +-
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp
index e0fff26..9757d4c 100644
--- a/kernel/src/kernel.cpp
+++ b/kernel/src/kernel.cpp
@@ -209,7 +209,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
 		// Allocate memory for segment:
 		std::size_t nb_pages = (std::uint64_t(program_header.p_vaddr) % 0x1000 + program_header.p_memsz + 0x1000 - 1) / 0x1000;
 		for (std::size_t i = 0; i < nb_pages; i++) {
-			os::paging::setup_page(PML4T, program_header.p_vaddr + i * 0x1000, (program_header.flags & 2) >> 1, 1, true);
+			os::paging::setup_page(PML4T, program_header.p_vaddr + i * 0x1000, (program_header.flags & 2) >> 1, 1);
 		}
 		// Initialise memory for segment:
 		for (std::size_t i = 0; i < program_header.p_filesz; i++) {
@@ -224,7 +224,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
 	constexpr std::size_t stack_size = 16 * 0x1000 /* 64KiB */;
 	std::byte * const stack = (std::byte*)0x0000'8000'0000'0000 - stack_size;
 	for (std::size_t i = 0; i < stack_size / 0x1000 /* 64KiB */; i++) {
-		os::paging::setup_page(PML4T, stack + i * 0x1000, 1, 1, true);
+		os::paging::setup_page(PML4T, stack + i * 0x1000, 1, 1);
 	}
 
 	os::print("Loading ring 3 interrupts stack.\n");
diff --git a/kernel/src/paging.cpp b/kernel/src/paging.cpp
index 5996b25..dc9ec73 100644
--- a/kernel/src/paging.cpp
+++ b/kernel/src/paging.cpp
@@ -14,7 +14,7 @@
 #include "paging.hpp"
 #include "serial.hpp"
 
-void os::paging::setup_page(os::paging::PML4T& PML4T, const void* vaddr, bool R_W, bool U_S, bool must_be_unmapped) {
+void os::paging::setup_page(os::paging::PML4T& PML4T, const void* vaddr, bool R_W, bool U_S) {
 	const auto indices = os::paging::calc_page_table_indices(vaddr);
 	if (PML4T.contents[indices.pml4e].P == 0) {
 		PML4T.contents[indices.pml4e] = {.P = 1, .R_W = 1, .U_S = U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0};
@@ -26,22 +26,26 @@ void os::paging::setup_page(os::paging::PML4T& PML4T, const void* vaddr, bool R_
 		PDPT.contents[indices.pdpe] = {.non_page = {.P = 1, .R_W = 1, .U_S = U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}};
 		const auto PDT_alloc = os::paging::page_allocator.allocate(1);
 		set_base_address(PDPT.contents[indices.pdpe], os::phys_ptr<os::paging::PDT>(PDT_alloc.ptr.get_phys_addr()));
+	} else {
+		assert(PDPT.contents[indices.pdpe].non_page.zero == 0,
+			"Cannot map memory address 0x{} because it is inside a 1GiB page", std::uintptr_t(vaddr));
 	}
 	os::paging::PDT& PDT = *get_base_address(PDPT.contents[indices.pdpe]);
 	if (PDT.contents[indices.pde].non_page.P == 0) {
 		PDT.contents[indices.pde] = {.non_page = {.P = 1, .R_W = 1, .U_S = U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}};
 		const auto PT_alloc = os::paging::page_allocator.allocate(1);
 		set_base_address(PDT.contents[indices.pde], os::phys_ptr<os::paging::PT>(PT_alloc.ptr.get_phys_addr()));
-	}
-	os::paging::PT& PT = *get_base_address(PDT.contents[indices.pde]);
-	if (PT.contents[indices.pe].P == 0) {
-		PT.contents[indices.pe] = {.P = 1, .R_W = R_W, .U_S = U_S, .PWT = 0, .PCD = 0, .PAT = 0, .G = 0, .base_address = 0, .NX = 0};
-		const auto page_alloc = os::paging::page_allocator.allocate(1);
-		set_page_base_address(PT.contents[indices.pe], os::phys_ptr<os::paging::page>(page_alloc.ptr.get_phys_addr()));
-		invlpg(vaddr);
 	} else {
-		os::assert(!must_be_unmapped, "Memory at address 0x{} has already been mapped.", std::uintptr_t(vaddr));
+		assert(PDT.contents[indices.pde].non_page.zero == 0,
+			"Cannot map memory address 0x{} because it is inside a 2MiB page", std::uintptr_t(vaddr));
 	}
+	os::paging::PT& PT = *get_base_address(PDT.contents[indices.pde]);
+	os::assert(PT.contents[indices.pe].P == 0, "Memory at address 0x{} has already been mapped.", std::uintptr_t(vaddr));
+	PT.contents[indices.pe] =
+		{.P = 1, .R_W = R_W, .U_S = U_S, .PWT = 0, .PCD = 0, .PAT = 0, .G = (indices.pml4e < 128) ? 0ul : 1ul, .base_address = 0, .NX = 0};
+	const auto page_alloc = os::paging::page_allocator.allocate(1);
+	set_page_base_address(PT.contents[indices.pe], os::phys_ptr<os::paging::page>(page_alloc.ptr.get_phys_addr()));
+	invlpg(vaddr);
 }
 
 namespace {
diff --git a/kernel/src/paging.hpp b/kernel/src/paging.hpp
index a9a1946..9fcb6ee 100644
--- a/kernel/src/paging.hpp
+++ b/kernel/src/paging.hpp
@@ -235,7 +235,7 @@ constexpr page_table_indices calc_page_table_indices(const void* ptr) {
 	};
 }
 
-void setup_page(PML4T& PML4T, const void* vaddr, bool R_W, bool U_S, bool must_be_unmapped);
+void setup_page(PML4T& PML4T, const void* vaddr, bool R_W, bool U_S);
 
 // For all present page mappings, calls f(virtual address, physical address, page size in bytes (4KiB, 2MiB or 1GiB)).
 void on_all_pages(const PML4T& PML4T, void f(page*, phys_ptr<page>, std::size_t));
-- 
2.46.0