From 8f3f5ac8cec41279fe4a528904541cb372fc371b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 26 Jun 2019 22:27:41 +0200 Subject: [PATCH] Kernel: Automatically populate page tables with lazy kernel regions. If we get an NP page fault in a process, and the fault address is in the kernel address range (anywhere above 0xc0000000), we probably just need to copy the page table info over from the kernel page directory. The kernel doesn't allocate address space until it's needed, and when it does allocate some, it only puts the info in the kernel page directory, and any *new* page directories created from that point on. Existing page directories need to be updated, and that's what this patch fixes. --- Kernel/VM/MemoryManager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 2d01fda98e..2eca7940fa 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -405,6 +405,14 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault) dbgprintf("MM: handle_page_fault(%w) at L%x\n", fault.code(), fault.vaddr().get()); #endif ASSERT(fault.vaddr() != m_quickmap_addr); + if (fault.is_not_present() && fault.vaddr().get() >= 0xc0000000) { + dword page_directory_index = (fault.vaddr().get() >> 22) & 0x3ff; + if (kernel_page_directory().entries()[page_directory_index].is_present()) { + current->process().page_directory().entries()[page_directory_index].copy_from({}, kernel_page_directory().entries()[page_directory_index]); + dbgprintf("NP(kernel): copying new kernel mapping for L%x into process\n", fault.vaddr().get()); + return PageFaultResponse::Continue; + } + } auto* region = region_from_vaddr(current->process(), fault.vaddr()); if (!region) { kprintf("NP(error) fault at invalid address L%x\n", fault.vaddr().get());