diff --git a/zion/interrupt/interrupt.cpp b/zion/interrupt/interrupt.cpp index bbdb400..ab2d8c9 100644 --- a/zion/interrupt/interrupt.cpp +++ b/zion/interrupt/interrupt.cpp @@ -43,6 +43,7 @@ InterruptDescriptor CreateDescriptor(void isr(void)) { } struct InterruptFrame { + uint64_t cr2; uint64_t rax; uint64_t rbx; uint64_t rcx; @@ -90,14 +91,14 @@ extern "C" void interrupt_protection_fault(InterruptFrame* frame) { extern "C" void isr_page_fault(); extern "C" void interrupt_page_fault(InterruptFrame* frame) { - uint64_t cr2; - asm volatile("mov %%cr2, %0" : "=r"(cr2)); - - if (gScheduler->CurrentProcess().vmas()->HandlePageFault(cr2)) { - return; + uint64_t err = frame->error_code; + if ((err & 0x1) == 0) { + // Page not present error may be resolveable. + if (gScheduler->CurrentProcess().vmas()->HandlePageFault(frame->cr2)) { + return; + } } dbgln("Unhandled Page Fault:"); - uint64_t err = frame->error_code; if (err & 0x1) { dbgln("Page Protection"); } else { @@ -119,7 +120,7 @@ extern "C" void interrupt_page_fault(InterruptFrame* frame) { } dbgln("rip: %m", frame->rip); - dbgln("addr: %m", cr2); + dbgln("addr: %m", frame->cr2); panic("PF"); } diff --git a/zion/interrupt/interrupt_enter.s b/zion/interrupt/interrupt_enter.s index cf6db7a..d6bc5b3 100644 --- a/zion/interrupt/interrupt_enter.s +++ b/zion/interrupt/interrupt_enter.s @@ -14,9 +14,12 @@ push %rcx # (Return Address) push %rbx push %rax + mov %cr2, %rax + push %rax .endm .macro interrupt_exit + add $8, %rsp pop %rax pop %rbx pop %rcx @@ -26,11 +29,11 @@ pop %r8 pop %r9 pop %r10 - pop %r10 - pop %r10 - pop %r10 - pop %r10 - pop %r10 + pop %r11 + pop %r12 + pop %r13 + pop %r14 + pop %r15 pop %rbp add $8, %rsp # Remove error code.