summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-08-06 14:01:29 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-08-06 15:06:31 +0200
commita0bb592b4f8ddfb0853befe8b22ef9b5e968bfd6 (patch)
treeed7bde06854465d3eeec94f3f266622ad4faac16 /Kernel
parentda615e46cdfb6a7a563dd47f6adc61303365eb84 (diff)
downloadserenity-a0bb592b4f8ddfb0853befe8b22ef9b5e968bfd6.zip
Kernel: Allow zero-fill page faults on kernel-only pages
We were short-circuiting the page fault handler a little too eagerly for page-not-present faults in kernel memory. If the current page directory already has up-to-date mapps for kernel memory, allow it to progress to checking for zero-fill conditions. This will enable us to have lazily populated kernel regions.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/VM/MemoryManager.cpp10
1 files changed, 6 insertions, 4 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp
index fd0ff993ac..ae73156766 100644
--- a/Kernel/VM/MemoryManager.cpp
+++ b/Kernel/VM/MemoryManager.cpp
@@ -416,12 +416,14 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault)
#endif
ASSERT(fault.vaddr() != m_quickmap_addr);
if (fault.type() == PageFault::Type::PageNotPresent && fault.vaddr().get() >= 0xc0000000) {
+ auto* current_page_directory = reinterpret_cast<PageDirectoryEntry*>(cpu_cr3());
u32 page_directory_index = (fault.vaddr().get() >> 22) & 0x3ff;
auto& kernel_pde = kernel_page_directory().entries()[page_directory_index];
- if (kernel_pde.is_present()) {
- dbgprintf("NP(kernel): copying new kernel mapping for L%x into current page directory\n", fault.vaddr().get());
- auto* current_page_directory = reinterpret_cast<PageDirectoryEntry*>(cpu_cr3());
- current_page_directory[page_directory_index].copy_from({}, kernel_pde);
+ auto& current_pde = current_page_directory[page_directory_index];
+
+ if (kernel_pde.is_present() && !current_pde.is_present()) {
+ dbg() << "NP(kernel): Copying new kernel mapping for " << fault.vaddr() << " into current page directory";
+ current_pde.copy_from({}, kernel_pde);
flush_tlb(fault.vaddr().page_base());
return PageFaultResponse::Continue;
}