refactor: re-structure the kernel address space for a more integral layout.
[lunaix-os.git] / lunaix-os / kernel / asm / x86 / pfault.c
index 9d5e1d1bdbe2bc10fab8514bec0fe71f6b915bb7..34589cbe6685fc60b49aeb65fcf95819cef4e4cf 100644 (file)
@@ -28,7 +28,20 @@ intr_routine_page_fault(const isr_param* param)
         goto segv_term;
     }
 
-    struct mm_region* hit_region = region_get(__current, ptr);
+    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->mm.regions, ptr);
 
     if (!hit_region) {
         // Into the void...
@@ -77,4 +90,22 @@ segv_term:
             param->eip);
     terminate_proc(LXSEGFAULT);
     // should not reach
+}
+
+int
+do_kernel(v_mapping* mapping)
+{
+    uintptr_t addr = mapping->va;
+    if (addr >= KHEAP_START && addr < PROC_START) {
+        // 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