diff --git a/arch/x86/kernel/memory.c b/arch/x86/kernel/memory.c index 43285b79..01108e06 100644 --- a/arch/x86/kernel/memory.c +++ b/arch/x86/kernel/memory.c @@ -2261,6 +2261,7 @@ int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t if ((ustart < vm->region.user_start) || (vm->region.user_end <= ustart) || ((vm->region.user_end - ustart) < siz)) { + kprintf("%s: error: out of user range\n", __FUNCTION__); return -EFAULT; } @@ -2268,6 +2269,7 @@ int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t for (addr = ustart & PAGE_MASK; addr < uend; addr += PAGE_SIZE) { error = page_fault_process_vm(vm, (void *)addr, reason); if (error) { + kprintf("%s: error: PF for %p failed\n", __FUNCTION__, addr); return error; } } @@ -2283,6 +2285,7 @@ int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t error = ihk_mc_pt_virt_to_phys(vm->address_space->page_table, from, &pa); if (error) { + kprintf("%s: error: resolving physical address or %p\n", __FUNCTION__, from); return error; } diff --git a/executer/kernel/mcctrl/syscall.c b/executer/kernel/mcctrl/syscall.c index db4d75e8..e14ffb2b 100644 --- a/executer/kernel/mcctrl/syscall.c +++ b/executer/kernel/mcctrl/syscall.c @@ -899,7 +899,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa) error = vfs_fstat(fd, &st); if (error) { - dprintk("pager_req_create(%d,%lx):vfs_stat failed. %d\n", fd, (long)result_pa, error); + printk("pager_req_create(%d,%lx):vfs_stat failed. %d\n", fd, (long)result_pa, error); goto out; } if (S_ISCHR(st.mode) && (MAJOR(st.rdev) == 1)) { @@ -914,7 +914,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa) file = fget(fd); if (!file) { error = -EBADF; - dprintk("pager_req_create(%d,%lx):file not found. %d\n", fd, (long)result_pa, error); + printk("pager_req_create(%d,%lx):file not found. %d\n", fd, (long)result_pa, error); goto out; } @@ -937,7 +937,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa) } if (!(maxprot & PROT_READ)) { error = -EACCES; - dprintk("pager_req_create(%d,%lx):cannot read file. %d\n", fd, (long)result_pa, error); + printk("pager_req_create(%d,%lx):cannot read file. %d\n", fd, (long)result_pa, error); goto out; } @@ -1209,7 +1209,7 @@ struct pager_map_result { }; static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off, - uintptr_t result_rpa, int prot) + uintptr_t result_rpa, int prot_and_flags) { const ihk_device_t dev = ihk_os_to_dev(os); const off_t pgoff = off / PAGE_SIZE; @@ -1237,27 +1237,33 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off, } maxprot = 0; - if (file->f_mode & FMODE_READ) { + if ((file->f_mode & FMODE_READ) && + (prot_and_flags ? (prot_and_flags & PROT_READ) : 1)) { maxprot |= PROT_READ; } - if ((file->f_mode & FMODE_WRITE) && (prot ? (prot & PROT_WRITE) : 1)) { + if ((file->f_mode & FMODE_WRITE) && + (prot_and_flags ? (prot_and_flags & PROT_WRITE) : 1)) { maxprot |= PROT_WRITE; } - if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC)) { + if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC) && + (prot_and_flags ? (prot_and_flags & PROT_EXEC) : 1)) { maxprot |= PROT_EXEC; } down_write(¤t->mm->mmap_sem); #define ANY_WHERE 0 + if (prot_and_flags & MAP_LOCKED) prot_and_flags |= MAP_POPULATE; #if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) - va = do_mmap_pgoff(file, ANY_WHERE, len, maxprot, MAP_SHARED, pgoff); + va = do_mmap_pgoff(file, ANY_WHERE, len, maxprot, + MAP_SHARED | (prot_and_flags & (MAP_POPULATE | MAP_LOCKED)), pgoff); #endif up_write(¤t->mm->mmap_sem); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) - va = vm_mmap(file, ANY_WHERE, len, maxprot, MAP_SHARED, pgoff << PAGE_SHIFT); + va = vm_mmap(file, ANY_WHERE, len, maxprot, MAP_SHARED | + (prot_and_flags & (MAP_POPULATE | MAP_LOCKED)), pgoff << PAGE_SHIFT); #endif if (IS_ERR_VALUE(va)) { @@ -1271,8 +1277,8 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off, pager->map_len = len; pager->map_off = off; - dprintk("pager_req_map(%s): 0x%lx - 0x%lx (len: %lu)\n", - file->f_dentry->d_name.name, va, va + len, len); + dprintk("pager_req_map(%s): 0x%lx - 0x%lx (len: %lu), map_off: %lu\n", + file->f_dentry->d_name.name, va, va + len, len, off); phys = ihk_device_map_memory(dev, result_rpa, sizeof(*resp)); resp = ihk_device_map_virtual(dev, phys, sizeof(*resp), NULL, 0); @@ -1309,6 +1315,7 @@ static int pager_req_pfn(ihk_os_t os, uintptr_t handle, off_t off, uintptr_t ppf pte_t *pte; uintptr_t phys; uintptr_t *ppfn; + int page_fault_attempted = 0; dprintk("pager_req_pfn(%p,%lx,%lx)\n", os, handle, off); @@ -1324,6 +1331,7 @@ static int pager_req_pfn(ihk_os_t os, uintptr_t handle, off_t off, uintptr_t ppf pfn = PFN_VALID; /* デフォルトは not present */ down_read(¤t->mm->mmap_sem); +retry: pgd = pgd_offset(current->mm, va); if (!pgd_none(*pgd) && !pgd_bad(*pgd) && pgd_present(*pgd)) { pud = pud_offset(pgd, va); @@ -1346,6 +1354,33 @@ static int pager_req_pfn(ihk_os_t os, uintptr_t handle, off_t off, uintptr_t ppf } } } + + /* If not present, try to fault it */ + if (!(pfn & PFN_PRESENT) && !page_fault_attempted) { + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; + struct vm_area_struct *vma; + int fault; + + flags |= FAULT_FLAG_USER; + + vma = find_vma(current->mm, va); + if (!vma || (va < vma->vm_start)) { + printk("%s: couldn't find VMA for va %lx\n", __FUNCTION__, va); + error = -EINVAL; + goto out_release; + } + + fault = handle_mm_fault(current->mm, vma, va, flags); + if (fault != 0) { + printk("%s: error: faulting %lx at off: %lu\n", + __FUNCTION__, va, off); + } + + page_fault_attempted = 1; + goto retry; + } + +out_release: up_read(¤t->mm->mmap_sem); phys = ihk_device_map_memory(dev, ppfn_rpa, sizeof(*ppfn)); diff --git a/kernel/devobj.c b/kernel/devobj.c index fdf68241..6d4ba3d7 100644 --- a/kernel/devobj.c +++ b/kernel/devobj.c @@ -79,7 +79,7 @@ static struct memobj *to_memobj(struct devobj *devobj) * devobj */ int devobj_create(int fd, size_t len, off_t off, struct memobj **objp, int *maxprotp, - int prot) + int prot, int populate_flags) { ihk_mc_user_context_t ctx; struct pager_map_result result; // XXX: assumes contiguous physical @@ -116,7 +116,7 @@ int devobj_create(int fd, size_t len, off_t off, struct memobj **objp, int *maxp ihk_mc_syscall_arg2(&ctx) = len; ihk_mc_syscall_arg3(&ctx) = off; ihk_mc_syscall_arg4(&ctx) = virt_to_phys(&result); - ihk_mc_syscall_arg5(&ctx) = prot; + ihk_mc_syscall_arg5(&ctx) = prot | populate_flags; error = syscall_generic_forwarding(__NR_mmap, &ctx); if (error) { @@ -206,7 +206,7 @@ static void devobj_release(struct memobj *memobj) static int devobj_get_page(struct memobj *memobj, off_t off, int p2align, uintptr_t *physp, unsigned long *flag) { - const off_t pgoff = off >> PAGE_SHIFT; + const off_t pgoff = off / PAGE_SIZE; struct devobj *obj = to_devobj(memobj); int error; uintptr_t pfn; @@ -218,7 +218,7 @@ static int devobj_get_page(struct memobj *memobj, off_t off, int p2align, uintpt if ((pgoff < obj->pfn_pgoff) || ((obj->pfn_pgoff + obj->npages) <= pgoff)) { error = -EFBIG; - kprintf("devobj_get_page(%p %lx,%lx,%d): out of range. %d\n", memobj, obj->handle, off, p2align, error); + kprintf("%s: error: out of range: off: %lu, page off: %lu obj->npages: %d\n", __FUNCTION__, off, pgoff, obj->npages); goto out; } ix = pgoff - obj->pfn_pgoff; diff --git a/kernel/fileobj.c b/kernel/fileobj.c index 09052036..05beccf4 100644 --- a/kernel/fileobj.c +++ b/kernel/fileobj.c @@ -182,7 +182,7 @@ int fileobj_create(int fd, struct memobj **objp, int *maxprotp) error = syscall_generic_forwarding(__NR_mmap, &ctx); if (error) { - kprintf("fileobj_create(%d):create failed. %d\n", fd, error); + dkprintf("fileobj_create(%d):create failed. %d\n", fd, error); goto out; } diff --git a/kernel/include/memobj.h b/kernel/include/memobj.h index 35e255eb..78fd7876 100644 --- a/kernel/include/memobj.h +++ b/kernel/include/memobj.h @@ -142,6 +142,6 @@ struct shmid_ds; int shmobj_create(struct shmid_ds *ds, struct memobj **objp); int zeroobj_create(struct memobj **objp); int devobj_create(int fd, size_t len, off_t off, struct memobj **objp, int *maxprotp, - int prot); + int prot, int populate_flags); #endif /* HEADER_MEMOBJ_H */ diff --git a/kernel/process.c b/kernel/process.c index 8a783a97..baad39b9 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1641,6 +1641,18 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui "access denied. %d\n", ihk_mc_get_processor_id(), vm, fault_addr0, reason, error); + kprintf("%s: reason: %s%s%s%s%s%s%s%s\n", __FUNCTION__, + (reason & PF_PROT) ? "PF_PROT " : "", + (reason & PF_WRITE) ? "PF_WRITE " : "", + (reason & PF_USER) ? "PF_USER " : "", + (reason & PF_RSVD) ? "PF_RSVD " : "", + (reason & PF_INSTR) ? "PF_INSTR " : "", + (reason & PF_PATCH) ? "PF_PATCH " : "", + (reason & PF_POPULATE) ? "PF_POPULATE " : ""); + kprintf("%s: range->flag & (%s%s%s)\n", __FUNCTION__, + (range->flag & VR_PROT_READ) ? "VR_PROT_READ " : "", + (range->flag & VR_PROT_WRITE) ? "VR_PROT_WRITE " : "", + (range->flag & VR_PROT_EXEC) ? "VR_PROT_EXEC " : ""); if (((range->flag & VR_PROT_MASK) == VR_PROT_NONE)) kprintf("if (((range->flag & VR_PROT_MASK) == VR_PROT_NONE))\n"); if (((reason & PF_WRITE) && !(reason & PF_PATCH))) diff --git a/kernel/syscall.c b/kernel/syscall.c index 3224f99c..062f5656 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1097,7 +1097,7 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot, } #endif if (error == -ESRCH) { - kprintf("do_mmap:hit non VREG\n"); + dkprintf("do_mmap:hit non VREG\n"); /* * XXX: temporary: * @@ -1108,10 +1108,17 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot, vrflags &= ~VR_MEMTYPE_MASK; vrflags |= VR_MEMTYPE_UC; } - error = devobj_create(fd, len, off, &memobj, &maxprot, prot); + error = devobj_create(fd, len, off, &memobj, &maxprot, + prot, (flags & (MAP_POPULATE | MAP_LOCKED))); + + if (!error) { + dkprintf("%s: device fd: %d off: %lu mapping at %p - %p\n", + __FUNCTION__, fd, off, addr, addr + len); + } } if (error) { - ekprintf("do_mmap:fileobj_create failed. %d\n", error); + kprintf("%s: error: file mapping failed, fd: %d, error: %d\n", + __FUNCTION__, error); goto out; } } @@ -1181,9 +1188,12 @@ out: if (!error && populated_mapping) { error = populate_process_memory(thread->vm, (void *)addr, len); if (error) { - ekprintf("do_mmap:populate_process_memory" - "(%p,%p,%lx) failed %d\n", - thread->vm, (void *)addr, len, error); + ekprintf("%s: error :populate_process_memory" + "vm: %p, addr: %p, len: %d (flags: %s%s) failed %d\n", __FUNCTION__, + thread->vm, (void *)addr, len, + (flags & MAP_POPULATE) ? "MAP_POPULATE " : "", + (flags & MAP_LOCKED) ? "MAP_LOCKED ": "", + error); /* * In this case, * the mapping established by this call should be unmapped @@ -5574,7 +5584,7 @@ SYSCALL_DECLARE(sched_setaffinity) len = MIN2(len, sizeof(k_cpu_set)); if (copy_from_user(&k_cpu_set, u_cpu_set, len)) { - kprintf("%s:%d copy_from_user failed.\n", __FILE__, __LINE__); + kprintf("%s: error: copy_from_user failed for %p:%d\n", __FUNCTION__, u_cpu_set, len); return -EFAULT; }