From d5b1d72396000acc0a7d083ab7cff893a98352b4 Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 22 Jan 2023 14:46:03 +0100 Subject: [PATCH] x86_64/MMU: Map the kernel page directory to virtual memory This avoids depending on the kernel address space to create a new userspace one, since there is no physical memory access. This was fine for a single process, since its address space was created from the kernel one and no more address spaces were created, but for two or more, this started to become problematic, since we would create one address space while being in another process's address space, which has no direct mapping of physical memory. --- kernel/src/arch/x86_64/MMU.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index f2bf8cf3..2bd6ee49 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -1,4 +1,5 @@ #include "arch/MMU.h" +#include "Log.h" #include "memory/MemoryManager.h" #include #include @@ -9,6 +10,7 @@ #pragma GCC diagnostic ignored "-Wconversion" PageDirectory* g_kernel_directory; +u64 g_kernel_directory_virt; void PageTableEntry::set_address(u64 addr) { @@ -278,12 +280,18 @@ namespace MMU { PageDirectory* const dir = get_page_directory(); g_kernel_directory = dir; + const u64 paddr = (u64)dir; PageTableEntry& recursive_entry = dir->entries[rindex]; recursive_entry.read_write = true; recursive_entry.present = true; recursive_entry.set_address(paddr); flush_all(); + + g_kernel_directory_virt = + MemoryManager::get_kernel_mapping_for_frames((u64)dir, 1, MMU::ReadWrite | MMU::NoExecute).value(); + + kdbgln("MMU init page directory (ring0): virt %#.16lx, phys %p", g_kernel_directory_virt, g_kernel_directory); } Result create_page_directory_for_userspace() @@ -298,7 +306,9 @@ namespace MMU recursive_entry.present = true; recursive_entry.set_address(directory_phys); - directory->entries[511] = g_kernel_directory->entries[511]; + kdbgln("MMU init page directory (ring3): virt %p, phys %#.16lx", directory, directory_phys); + + directory->entries[511] = ((PageDirectory*)g_kernel_directory_virt)->entries[511]; // From now on, we're only going to use the physical address, since accessing the PageDirectory will be dealt // with using recursive mapping. So let's make sure we don't leak any VM.