diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index b9d19ba5..83a98958 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -600,6 +600,38 @@ static void __return_syscall(struct mcctrl_channel *c, int ret) c->param.response_va->status = 1; } +static void clear_pte_range(uintptr_t addr, uintptr_t len) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + uintptr_t start; + uintptr_t end; + + down_read(&mm->mmap_sem); + vma = find_vma(mm, 0); + if (!vma) { + printk("clear_pte_range(%lx,%lx):find_vma(0) failed\n", + addr, len); + up_read(&mm->mmap_sem); + return; + } + + start = addr; + end = addr + len; + if (start < vma->vm_start) { + start = vma->vm_start; + } + if (vma->vm_end < end) { + end = vma->vm_end; + } + if (start < end) { + zap_vma_ptes(vma, start, end-start); + } + + up_read(&mm->mmap_sem); + return; +} + int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c, struct syscall_request *sc) { int error; @@ -607,6 +639,11 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c, struct syscall dprintk("__do_in_kernel_syscall(%p,%p,%p %ld)\n", os, c, sc, sc->number); switch (sc->number) { + case __NR_munmap: + clear_pte_range(sc->args[0], sc->args[1]); + ret = 0; + break; + default: error = -ENOSYS; goto out; diff --git a/kernel/syscall.c b/kernel/syscall.c index be321bc1..243d7cd6 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -256,6 +256,21 @@ SYSCALL_DECLARE(exit_group) return 0; } +static void clear_host_pte(uintptr_t addr, size_t len) +{ + ihk_mc_user_context_t ctx; + long lerror; + + ihk_mc_syscall_arg0(&ctx) = addr; + ihk_mc_syscall_arg1(&ctx) = len; + + lerror = syscall_generic_forwarding(__NR_munmap, &ctx); + if (lerror) { + kprintf("clear_host_pte failed. %ld\n", lerror); + } + return; +} + static int do_munmap(void *addr, size_t len) { int error; @@ -358,6 +373,7 @@ SYSCALL_DECLARE(mmap) void *p; int vrflags; intptr_t phys; + int unmapped = 0; dkprintf("[%d]sys_mmap(%lx,%lx,%x,%x,%d,%lx)\n", ihk_mc_get_processor_id(), @@ -422,6 +438,7 @@ SYSCALL_DECLARE(mmap) if (flags & MAP_FIXED) { /* clear specified address range */ + unmapped = 1; error = do_munmap((void *)addr, len); if (error) { ekprintf("sys_mmap:do_munmap(%lx,%lx) failed. %d\n", @@ -525,6 +542,9 @@ SYSCALL_DECLARE(mmap) error = 0; out: + if (unmapped) { + clear_host_pte(addr, len); + } dkprintf("[%d]sys_mmap(%lx,%lx,%x,%x,%d,%lx): %ld %lx\n", ihk_mc_get_processor_id(), addr0, len0, prot, flags, fd, off, error, addr); @@ -557,6 +577,7 @@ SYSCALL_DECLARE(munmap) ihk_mc_spinlock_lock_noirq(&proc->vm->memory_range_lock); error = do_munmap((void *)addr, len); ihk_mc_spinlock_unlock_noirq(&proc->vm->memory_range_lock); + clear_host_pte(addr, len); out: dkprintf("[%d]sys_munmap(%lx,%lx): %d\n",