summaryrefslogtreecommitdiff
path: root/Kernel/VM/MemoryManager.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-01-19 13:44:53 +0100
committerAndreas Kling <kling@serenityos.org>2020-01-19 13:44:53 +0100
commit6eab7b398d2ce658b56f2650c721454a4e41fa2b (patch)
tree72fb36dcc59cb78e638530800001d68bf7a60fa6 /Kernel/VM/MemoryManager.cpp
parentad3f9317072697895436af93de71eb13f08c176e (diff)
downloadserenity-6eab7b398d2ce658b56f2650c721454a4e41fa2b.zip
Kernel: Make ProcessPagingScope restore CR3 properly
Instead of restoring CR3 to the current process's paging scope when a ProcessPagingScope goes out of scope, we now restore exactly whatever the CR3 value was when we created the ProcessPagingScope. This fixes breakage in situations where a process ends up with nested ProcessPagingScopes. This was making profiling very fragile, and with this change it's now possible to profile g++! :^)
Diffstat (limited to 'Kernel/VM/MemoryManager.cpp')
-rw-r--r--Kernel/VM/MemoryManager.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp
index a134e72dca..d55243d9b3 100644
--- a/Kernel/VM/MemoryManager.cpp
+++ b/Kernel/VM/MemoryManager.cpp
@@ -682,10 +682,15 @@ void MemoryManager::dump_kernel_regions()
ProcessPagingScope::ProcessPagingScope(Process& process)
{
ASSERT(current);
+ asm("movl %%cr3, %%eax"
+ : "=a"(m_previous_cr3));
MM.enter_process_paging_scope(process);
}
ProcessPagingScope::~ProcessPagingScope()
{
- MM.enter_process_paging_scope(current->process());
+ InterruptDisabler disabler;
+ current->tss().cr3 = m_previous_cr3;
+ asm volatile("movl %%eax, %%cr3" ::"a"(m_previous_cr3)
+ : "memory");
}