diff options
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 6 | ||||
-rw-r--r-- | Kernel/VM/PageDirectory.cpp | 8 | ||||
-rw-r--r-- | Kernel/VM/PageDirectory.h | 2 |
3 files changed, 16 insertions, 0 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index dcfb041828..540081d26c 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -479,6 +479,12 @@ void MemoryManager::enter_process_paging_scope(Process& process) { ASSERT(current); InterruptDisabler disabler; + + // NOTE: To prevent triple-faulting here, we have to ensure that the current stack + // is accessible to the incoming page directory. We achieve this by forcing + // an update of the kernel VM mappings in the entered scope's page directory. + process.page_directory().update_kernel_mappings(); + current->tss().cr3 = process.page_directory().cr3(); asm volatile("movl %%eax, %%cr3" ::"a"(process.page_directory().cr3()) : "memory"); diff --git a/Kernel/VM/PageDirectory.cpp b/Kernel/VM/PageDirectory.cpp index 3533d6cfa9..9cc949857a 100644 --- a/Kernel/VM/PageDirectory.cpp +++ b/Kernel/VM/PageDirectory.cpp @@ -57,3 +57,11 @@ void PageDirectory::flush(VirtualAddress vaddr) if (this == &MM.kernel_page_directory() || ¤t->process().page_directory() == this) MM.flush_tlb(vaddr); } + +void PageDirectory::update_kernel_mappings() +{ + // This ensures that the kernel virtual address space is up-to-date in this page directory. + // This may be necessary to avoid triple faulting when entering a process's paging scope + // whose mappings are out-of-date. + memcpy(entries() + 768, MM.kernel_page_directory().entries() + 768, sizeof(PageDirectoryEntry) * 256); +} diff --git a/Kernel/VM/PageDirectory.h b/Kernel/VM/PageDirectory.h index b6458c1055..3ffb438bbe 100644 --- a/Kernel/VM/PageDirectory.h +++ b/Kernel/VM/PageDirectory.h @@ -31,6 +31,8 @@ public: Process* process() { return m_process; } const Process* process() const { return m_process; } + void update_kernel_mappings(); + private: PageDirectory(Process&, const RangeAllocator* parent_range_allocator); explicit PageDirectory(PhysicalAddress); |