#include <lunaix/mm/region.h>
#include <lunaix/mm/valloc.h>
-#include <lunaix/mm/vmm.h>
-#include <lunaix/mm/pmm.h>
+#include <lunaix/mm/page.h>
#include <lunaix/mm/mmap.h>
#include <lunaix/process.h>
#include <lunaix/spike.h>
#include <lunaix/syscall.h>
#include <lunaix/syslog.h>
#include <lunaix/signal.h>
+#include <lunaix/kpreempt.h>
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/abi.h>
+#include <asm/mm_defs.h>
#include <klibc/string.h>
return;
}
- ptr_t start_vpn = PN(region->start);
- ptr_t end_vpn = PN(region->end);
- for (size_t i = start_vpn; i <= end_vpn; i++) {
- x86_pte_t* curproc = &PTE_MOUNTED(VMS_SELF, i);
- x86_pte_t* newproc = &PTE_MOUNTED(VMS_MOUNT_1, i);
-
- cpu_flush_page((ptr_t)newproc);
+ pfn_t start_pn = pfn(region->start);
+ pfn_t end_pn = pfn(region->end);
+
+ for (size_t i = start_pn; i <= end_pn; i++) {
+ pte_t* self = mkptep_pn(VMS_SELF, i);
+ pte_t* guest = mkptep_pn(VMS_MOUNT_1, i);
+ ptr_t va = page_addr(ptep_pfn(self));
if ((attr & REGION_MODE_MASK) == REGION_RSHARED) {
- // 如果读共享,则将两者的都标注为只读,那么任何写入都将会应用COW策略。
- cpu_flush_page((ptr_t)curproc);
- cpu_flush_page((ptr_t)(i << 12));
-
- *curproc = *curproc & ~PG_WRITE;
- *newproc = *newproc & ~PG_WRITE;
+ set_pte(self, pte_mkwprotect(*self));
+ set_pte(guest, pte_mkwprotect(*guest));
} else {
// 如果是私有页,则将该页从新进程中移除。
- *newproc = 0;
+ set_pte(guest, null_pte);
}
}
+
+ tlb_flush_vmr_all(region);
}
static inline void
static void
__dup_kernel_stack(struct thread* thread, ptr_t vm_mnt)
{
- ptr_t kstack_pn = PN(current_thread->kstack);
+ struct leaflet* leaflet;
+
+ ptr_t kstack_pn = pfn(current_thread->kstack);
+ kstack_pn -= pfn(KSTACK_SIZE);
// copy the kernel stack
- for (size_t i = 0; i < PN(KSTACK_SIZE); i++) {
- volatile x86_pte_t* orig_ppte = &PTE_MOUNTED(VMS_SELF, kstack_pn);
- x86_pte_t p = *orig_ppte;
- ptr_t kstack = kstack_pn * PG_SIZE;
+ pte_t* src_ptep = mkptep_pn(VMS_SELF, kstack_pn);
+ pte_t* dest_ptep = mkptep_pn(vm_mnt, kstack_pn);
+ for (size_t i = 0; i <= pfn(KSTACK_SIZE); i++) {
+ pte_t p = *src_ptep;
- if (guardian_page(p)) {
- vmm_set_mapping(vm_mnt, kstack, 0, 0, VMAP_GUARDPAGE);
+ if (pte_isguardian(p)) {
+ set_pte(dest_ptep, guard_pte);
} else {
- ptr_t ppa = vmm_dup_page(PG_ENTRY_ADDR(p));
- vmm_set_mapping(vm_mnt, kstack, ppa, p & 0xfff, 0);
+ leaflet = dup_leaflet(pte_leaflet(p));
+ i += ptep_map_leaflet(dest_ptep, p, leaflet);
}
- kstack_pn--;
+ src_ptep++;
+ dest_ptep++;
}
+
+ struct proc_mm* mm = vmspace(thread->process);
+ tlb_flush_mm_range(mm, kstack_pn, leaf_count(KSTACK_SIZE));
}
/*
return NULL;
}
- th->intr_ctx = current_thread->intr_ctx;
+ th->hstate = current_thread->hstate;
th->kstack = current_thread->kstack;
signal_dup_context(&th->sigctx);
pid_t
dup_proc()
{
+ no_preemption();
+
struct proc_info* pcb = alloc_process();
if (!pcb) {
syscall_result(ENOMEM);
}
__dup_fdtable(pcb);
- procvm_dup(pcb);
- vmm_mount_pd(VMS_MOUNT_1, vmroot(pcb));
+ struct proc_mm* mm = vmspace(pcb);
+ procvm_dupvms_mount(mm);
- struct thread* main_thread = dup_active_thread(VMS_MOUNT_1, pcb);
+ struct thread* main_thread = dup_active_thread(mm->vm_mnt, pcb);
if (!main_thread) {
syscall_result(ENOMEM);
- vmm_unmount_pd(VMS_MOUNT_1);
+ procvm_unmount(mm);
delete_process(pcb);
return -1;
}
region_maybe_cow(pos);
}
- vmm_unmount_pd(VMS_MOUNT_1);
+ procvm_unmount(mm);
commit_process(pcb);
commit_thread(main_thread);