Kernel address space isolation and make the kernel heap global to all processes.
[lunaix-os.git] / lunaix-os / kernel / process.c
index be7d423b3b6c36dc98654bb4df5e5570000e934c..de6eaf6625ef0136f21e7aa0f94af7b95cc8ef4e 100644 (file)
@@ -6,12 +6,10 @@
 
 LOG_MODULE("PROC")
 
-void dup_proc() {
-    pid_t pid = alloc_pid();
-
+void* __dup_pagetable(pid_t pid, uintptr_t mount_point) {
     void* ptd_pp = pmm_alloc_page(pid, PP_FGPERSIST);
     x86_page_table* ptd = vmm_fmap_page(pid, PG_MOUNT_1, ptd_pp, PG_PREM_RW);
-    x86_page_table* pptd = (x86_page_table*) L1_BASE_VADDR;
+    x86_page_table* pptd = (x86_page_table*) (mount_point | (0x3FF << 12));
 
     for (size_t i = 0; i < PG_MAX_ENTRIES - 1; i++)
     {
@@ -21,7 +19,7 @@ void dup_proc() {
             continue;
         }
         
-        x86_page_table* ppt = (x86_page_table*) L2_VADDR(i);
+        x86_page_table* ppt = (x86_page_table*) (mount_point | (i << 12));
         void* pt_pp = pmm_alloc_page(pid, PP_FGPERSIST);
         x86_page_table* pt = vmm_fmap_page(pid, PG_MOUNT_2, pt_pp, PG_PREM_RW);
 
@@ -36,7 +34,7 @@ void dup_proc() {
 
             // FIXME: 根据 mm_region 将读共享的页(如堆)标为只读,而私有的页(如栈),则复制;而写共享的页则无需更改flags
             if (va >= KSTACK_START) {
-                void* ppa = vmm_dup_page(va);
+                void* ppa = vmm_dup_page(pid, PG_ENTRY_ADDR(ppte));
                 ppte = ppte & 0xfff | (uintptr_t)ppa;
             }
             pt->entry[j] = ppte;
@@ -50,16 +48,39 @@ void dup_proc() {
     
     ptd->entry[PG_MAX_ENTRIES - 1] = NEW_L1_ENTRY(T_SELF_REF_PERM, ptd_pp);
 
+    return ptd_pp;
+}
+
+void* dup_pagetable(pid_t pid) {
+    return __dup_pagetable(pid, L2_BASE_VADDR);
+}
+
+void dup_proc() {
+    pid_t pid = alloc_pid();
+
+    /* 
+        FIXME: Problematic! It should mount the page table of process then copy it.
+        The current implementation copy the CURRENTLY loaded pgt.
+        However, dup_pagetable is designed to copy current loaded pgt.
+        
+    */
+
+    void* mnt_pt = vmm_mount_pd(__current->page_table);
+
+    void* pg = __dup_pagetable(pid, mnt_pt);
+
+    vmm_unmount_pd();
+
     struct proc_info pcb = (struct proc_info) {
         .created = clock_systime(),
         .pid = pid,
         .mm = __current->mm,
-        .page_table = ptd_pp,
+        .page_table = pg,
         .intr_ctx = __current->intr_ctx,
         .parent_created = __current->created
     };
 
-    // 正如同fork一样,返回两次。
+    // 正如同fork,返回两次。
     pcb.intr_ctx.registers.eax = 0;
     __current->intr_ctx.registers.eax = pid;