summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/VM/MemoryManager.cpp6
-rw-r--r--Kernel/VM/PageDirectory.cpp8
-rw-r--r--Kernel/VM/PageDirectory.h2
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() || &current->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);