diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-10-18 13:05:00 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-10-18 13:05:00 +0200 |
commit | f67d695254bf9e0d053e064ade4387665180f27d (patch) | |
tree | f6f74e40a76a89480780f1765e6851d16c234fe6 /Kernel/i386.cpp | |
parent | 89851a9ded3589551df0fe518acc302b5f907f79 (diff) | |
download | serenity-f67d695254bf9e0d053e064ade4387665180f27d.zip |
More paging stuff.
The test userspace process now runs at linear address 0x300000 which is
mapped to a dynamically allocated page from the MemoryManager. Cool!
Diffstat (limited to 'Kernel/i386.cpp')
-rw-r--r-- | Kernel/i386.cpp | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/Kernel/i386.cpp b/Kernel/i386.cpp index f455eaa8c9..1406df5a96 100644 --- a/Kernel/i386.cpp +++ b/Kernel/i386.cpp @@ -4,6 +4,7 @@ #include "i386.h" #include "Assertions.h" #include "Task.h" +#include "MemoryManager.h" struct DescriptorTablePointer { WORD size; @@ -67,8 +68,8 @@ asm( \ " iret\n" \ ); -EH_ENTRY(13) - +// 13: General Protection Fault +EH_ENTRY(13); void exception_13_handler() { auto& regs = *reinterpret_cast<RegisterDump*>(exception_state_dump); @@ -88,6 +89,42 @@ void exception_13_handler() Task::taskDidCrash(current); } +// 14: Page Fault +EH_ENTRY(14); +void exception_14_handler() +{ + dword faultAddress; + asm ("movl %%cr2, %%eax":"=a"(faultAddress)); + + auto& regs = *reinterpret_cast<RegisterDump*>(exception_state_dump); + kprintf("%s page fault: %u(%s), %s laddr=%p\n", + current->isRing0() ? "Kernel" : "User", + current->pid(), + current->name().characters(), + exception_code & 2 ? "write" : "read", + faultAddress); + + kprintf("exception code: %w\n", exception_code); + kprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs); + kprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx); + kprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, regs.esp, regs.esi, regs.edi); + + if (current->isRing0()) + HANG; + + auto response = MemoryManager::the().handlePageFault(PageFault(exception_code, LinearAddress(faultAddress))); + + if (response == PageFaultResponse::ShouldCrash) { + kprintf("Crashing after unresolved page fault\n"); + // NOTE: This will schedule a new task. + Task::taskDidCrash(current); + } else if (response == PageFaultResponse::Continue) { + kprintf("Continuing after resolved page fault\n"); + } else { + ASSERT_NOT_REACHED(); + } +} + #define EH(i, msg) \ static void _exception ## i () \ { \ @@ -227,7 +264,7 @@ void idt_init() registerInterruptHandler(0x0b, _exception11); registerInterruptHandler(0x0c, _exception12); registerInterruptHandler(0x0d, exception_13_entry); - registerInterruptHandler(0x0e, _exception14); + registerInterruptHandler(0x0e, exception_14_entry); registerInterruptHandler(0x0f, _exception15); registerInterruptHandler(0x10, _exception16); |