summaryrefslogtreecommitdiff
path: root/Kernel/i386.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-10-18 13:05:00 +0200
committerAndreas Kling <awesomekling@gmail.com>2018-10-18 13:05:00 +0200
commitf67d695254bf9e0d053e064ade4387665180f27d (patch)
treef6f74e40a76a89480780f1765e6851d16c234fe6 /Kernel/i386.cpp
parent89851a9ded3589551df0fe518acc302b5f907f79 (diff)
downloadserenity-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.cpp43
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);