X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/d1b1c8d9119229dbeed06cd252917e54a1cb77f6..28c176b668c841a3b7fb093faccf0efa39257603:/lunaix-os/kernel/mm/fault.c diff --git a/lunaix-os/kernel/mm/fault.c b/lunaix-os/kernel/mm/fault.c index e840b76..5bbf6ee 100644 --- a/lunaix-os/kernel/mm/fault.c +++ b/lunaix-os/kernel/mm/fault.c @@ -25,23 +25,25 @@ __gather_memaccess_info(struct fault_context* context) context->mm = vmspace(__current); - if (mnt < VMS_MOUNT_1) { + if (!vmnt_packed(ptep)) { refva = (ptr_t)ptep; goto done; } context->ptep_fault = true; - context->remote_fault = (mnt != VMS_SELF); + context->remote_fault = !active_vms(mnt); if (context->remote_fault && context->mm) { context->mm = context->mm->guest_mm; assert(context->mm); } + // unpack the ptep to reveal the one true va! + #if LnT_ENABLED(1) ptep = (pte_t*)page_addr(ptep_pfn(ptep)); mnt = ptep_vm_mnt(ptep); - if (mnt < VMS_MOUNT_1) { + if (!vmnt_packed(ptep)) { refva = (ptr_t)ptep; goto done; } @@ -50,7 +52,7 @@ __gather_memaccess_info(struct fault_context* context) #if LnT_ENABLED(2) ptep = (pte_t*)page_addr(ptep_pfn(ptep)); mnt = ptep_vm_mnt(ptep); - if (mnt < VMS_MOUNT_1) { + if (!vmnt_packed(ptep)) { refva = (ptr_t)ptep; goto done; } @@ -59,7 +61,7 @@ __gather_memaccess_info(struct fault_context* context) #if LnT_ENABLED(3) ptep = (pte_t*)page_addr(ptep_pfn(ptep)); mnt = ptep_vm_mnt(ptep); - if (mnt < VMS_MOUNT_1) { + if (!vmnt_packed(ptep)) { refva = (ptr_t)ptep; goto done; } @@ -68,7 +70,7 @@ __gather_memaccess_info(struct fault_context* context) ptep = (pte_t*)page_addr(ptep_pfn(ptep)); mnt = ptep_vm_mnt(ptep); - assert(mnt < VMS_MOUNT_1); + assert(!vmnt_packed(ptep)); refva = (ptr_t)ptep; done: @@ -174,14 +176,17 @@ __handle_anon_region(struct fault_context* fault) static void __handle_named_region(struct fault_context* fault) { + int errno = 0; struct mm_region* vmr = fault->vmr; struct v_file* file = vmr->mfile; + struct v_file_ops * fops = file->ops; pte_t pte = fault->resolving; ptr_t fault_va = page_aligned(fault->fault_va); u32_t mseg_off = (fault_va - vmr->start); u32_t mfile_off = mseg_off + vmr->foff; + size_t mapped_len = vmr->flen; // TODO Potentially we can get different order of leaflet here struct leaflet* region_part = alloc_leaflet(0); @@ -189,7 +194,25 @@ __handle_named_region(struct fault_context* fault) pte = pte_setprot(pte, region_pteprot(vmr)); ptep_map_leaflet(fault->fault_ptep, pte, region_part); - int errno = file->ops->read_page(file->inode, (void*)fault_va, mfile_off); + if (mseg_off < mapped_len) { + mapped_len = MIN(mapped_len - mseg_off, PAGE_SIZE); + } + else { + mapped_len = 0; + } + + if (mapped_len == PAGE_SIZE) { + errno = fops->read_page(file->inode, (void*)fault_va, mfile_off); + } + else { + leaflet_wipe(region_part); + + if (mapped_len) { + errno = fops->read(file->inode, + (void*)fault_va, mapped_len, mfile_off); + } + } + if (errno < 0) { ERROR("fail to populate page (%d)", errno); @@ -208,7 +231,7 @@ static void __handle_kernel_page(struct fault_context* fault) { // we must ensure only ptep fault is resolvable - if (fault->fault_va < VMS_MOUNT_1) { + if (!is_ptep(fault->fault_va)) { return; } @@ -341,4 +364,6 @@ intr_routine_page_fault(const struct hart_state* hstate) leaflet_return(fault.prealloc); } } + + tlb_flush_kernel(fault.fault_va); } \ No newline at end of file