diff options
author | Andreas Kling <kling@serenityos.org> | 2020-01-19 13:44:53 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-01-19 13:44:53 +0100 |
commit | 6eab7b398d2ce658b56f2650c721454a4e41fa2b (patch) | |
tree | 72fb36dcc59cb78e638530800001d68bf7a60fa6 /Kernel/VM/MemoryManager.cpp | |
parent | ad3f9317072697895436af93de71eb13f08c176e (diff) | |
download | serenity-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.cpp | 7 |
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"); } |