X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/14b86eca7f36eedde35cb47b41afc36f9097ea7c..61bcf0c65dac58d2f29ab40e016489c89ec8eec0:/lunaix-os/kernel/asm/x86/pfault.c diff --git a/lunaix-os/kernel/asm/x86/pfault.c b/lunaix-os/kernel/asm/x86/pfault.c index 9d5e1d1..15f11ee 100644 --- a/lunaix-os/kernel/asm/x86/pfault.c +++ b/lunaix-os/kernel/asm/x86/pfault.c @@ -20,6 +20,8 @@ kprintf(const char* fmt, ...) extern void __print_panic_msg(const char* msg, const isr_param* param); +extern void __kernel_heap_start; + void intr_routine_page_fault(const isr_param* param) { @@ -28,6 +30,19 @@ intr_routine_page_fault(const isr_param* param) goto segv_term; } + v_mapping mapping; + if (!vmm_lookup(ptr, &mapping)) { + goto segv_term; + } + + if (!SEL_RPL(param->cs)) { + // 如果是内核页错误…… + if (do_kernel(&mapping)) { + return; + } + goto segv_term; + } + struct mm_region* hit_region = region_get(__current, ptr); if (!hit_region) { @@ -77,4 +92,22 @@ segv_term: param->eip); terminate_proc(LXSEGFAULT); // should not reach +} + +int +do_kernel(v_mapping* mapping) +{ + uintptr_t addr = mapping->va; + if (addr >= &__kernel_heap_start && addr < L2_BASE_VADDR) { + // This is kernel heap page + uintptr_t pa = pmm_alloc_page(KERNEL_PID, 0); + *mapping->pte = (*mapping->pte & 0xfff) | pa | PG_PRESENT; + cpu_invplg(mapping->pte); + cpu_invplg(addr); + goto done; + } + + return 0; +done: + return 1; } \ No newline at end of file