1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 15:38:12 +00:00

Kernel: Fix triple-fault when clicking on SystemServer in SystemMonitor

The fault was happening when retrieving a current backtrace for the
SystemServer process.

To generate a backtrace, we go into the paging scope of the process,
meaning we temporarily switch to using its page directory as our own.

Because kernel VM is allocated on demand, it's possible for a process's
mappings above the 3GB mark to be out-of-date. Normally this just gets
fixed up transparently by the page fault handler (which simply copies
the PDE from the canonical MM.kernel_page_directory() into the current
process.)

However, if the current kernel *stack* is in a piece of memory that
the backtraced process lacks up-to-date PDE's for, we still get a page
fault, but are unable to handle it, since the CPU wants to push to the
stack as part of calling the page fault handler. So we're screwed and
it's a triple-fault.

Fix this by always updating the kernel VM mappings before switching
into a paging scope. In practical terms, this is a 1KB memcpy() that
happens when generating a backtrace, or doing exec().
This commit is contained in:
Andreas Kling 2019-11-27 12:40:42 +01:00
parent 5b8cf2ee23
commit 2d1bcce34a
3 changed files with 16 additions and 0 deletions

View file

@ -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");