From a79a0a618d2b0219307b77ecd721cba34edaf117 Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Thu, 7 Aug 2014 16:16:13 +0900 Subject: [PATCH 1/7] drop VM_IO because it's not MMIO --- executer/kernel/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index 946f4827..3ce5f454 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -429,7 +429,7 @@ static struct vm_operations_struct rus_vmops = { static int rus_mmap(struct file *file, struct vm_area_struct *vma) { - vma->vm_flags |= VM_IO | VM_RESERVED | VM_DONTEXPAND | VM_PFNMAP; + vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND | VM_PFNMAP; vma->vm_ops = &rus_vmops; return 0; } From fe39d56554677740ce4aec51d49dd39da57e8060 Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Thu, 7 Aug 2014 16:36:33 +0900 Subject: [PATCH 2/7] use mixed mapping instead of PFN mapping --- executer/kernel/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index 3ce5f454..c2257d02 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -429,7 +429,7 @@ static struct vm_operations_struct rus_vmops = { static int rus_mmap(struct file *file, struct vm_area_struct *vma) { - vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND | VM_PFNMAP; + vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND | VM_MIXEDMAP; vma->vm_ops = &rus_vmops; return 0; } From b4910ec33f0786b15e461ee3f0848604f5d1439d Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Thu, 7 Aug 2014 16:03:36 +0900 Subject: [PATCH 3/7] use vm_insert_page() if 'struct page' exists --- executer/kernel/syscall.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index c2257d02..f41f993d 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -405,6 +405,19 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) pfn = phys >> PAGE_SHIFT; #if USE_VM_INSERT_PFN for (pix = 0; pix < (pgsize / PAGE_SIZE); ++pix) { + struct page *page; + + if (pfn_valid(pfn+pix)) { + page = pfn_to_page(pfn+pix); + if (!page_count(page)) { + get_page(page); + } + error = vm_insert_page(vma, rva+(pix*PAGE_SIZE), page); + if (error) { + printk("vm_insert_page: %d\n", error); + } + } + else error = vm_insert_pfn(vma, rva+(pix*PAGE_SIZE), pfn+pix); if (error) { break; From 8c1c8a40d1a681fdcfd8d536a824d4eeae2bfac8 Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Thu, 7 Aug 2014 12:31:48 +0900 Subject: [PATCH 4/7] use madvise() when zap_vma_ptes() fails --- executer/kernel/syscall.c | 21 ++++++++++++++------- executer/user/mcexec.c | 6 +++++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index f41f993d..fb7d4bc9 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -1138,13 +1138,16 @@ out: return (IS_ERR_VALUE(map))? (int)map: 0; } -static void clear_pte_range(uintptr_t start, uintptr_t len) +static int clear_pte_range(uintptr_t start, uintptr_t len) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; uintptr_t addr; uintptr_t end; + int error; + int ret; + ret = 0; down_read(&mm->mmap_sem); addr = start; while (addr < (start + len)) { @@ -1161,14 +1164,15 @@ static void clear_pte_range(uintptr_t start, uintptr_t len) end = vma->vm_end; } if (addr < end) { - zap_vma_ptes(vma, addr, end-addr); - dprintk("clear_pte_range() 0x%lx - 0x%lx OK\n", - vma->vm_start, vma->vm_end); + error = zap_vma_ptes(vma, addr, end-addr); + if (ret == 0) { + ret = error; + } } addr = end; } up_read(&mm->mmap_sem); - return; + return ret; } /** @@ -1306,8 +1310,11 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c, struct syscall ppd->pid, ppd->rpgtable); } - clear_pte_range(sc->args[0], sc->args[1]); - ret = 0; + error = clear_pte_range(sc->args[0], sc->args[1]); + if (error) { + error = -ENOSYS; + goto out; + } break; case __NR_mprotect: diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index a8f08d89..d3661911 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -1157,12 +1157,16 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) return w.sr.args[0]; case __NR_mmap: - case __NR_munmap: case __NR_mprotect: /* reserved for internal use */ do_syscall_return(fd, cpu, -ENOSYS, 0, 0, 0, 0); break; + case __NR_munmap: + ret = madvise((void *)w.sr.args[0], w.sr.args[1], MADV_DONTNEED); + do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); + break; + #ifdef USE_SYSCALL_MOD_CALL case 303:{ __dprintf("mcexec.c,mod_cal,mod=%ld,cmd=%ld\n", w.sr.args[0], w.sr.args[1]); From 431adf7e7c293bbb908576289bff3a444eaad4fd Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Fri, 29 Aug 2014 16:02:52 +0900 Subject: [PATCH 5/7] mcctrl: report success when __NR_munmap succeeds --- executer/kernel/syscall.c | 1 + 1 file changed, 1 insertion(+) diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index fb7d4bc9..0d6b1fd6 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -1315,6 +1315,7 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c, struct syscall error = -ENOSYS; goto out; } + ret = 0; break; case __NR_mprotect: From f2e0e42ba4a51a247270a2291da6ffcd3238ccb8 Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Fri, 29 Aug 2014 16:03:07 +0900 Subject: [PATCH 6/7] mcexec: report proper error when __NR_munmap fails --- executer/user/mcexec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index d3661911..6d03b28b 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -1164,6 +1164,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) case __NR_munmap: ret = madvise((void *)w.sr.args[0], w.sr.args[1], MADV_DONTNEED); + SET_ERR(ret); do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); break; From 4177f1c9cd4ce2e9338ce7b935ca95f00687a3dd Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Fri, 29 Aug 2014 20:28:33 +0900 Subject: [PATCH 7/7] TODO: get_page()ed pages have to be put_page()ed The pages which get_page() has been called with should be recorded. Because these pages have to be passed to put_page() before they are freed. --- executer/kernel/syscall.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index 0d6b1fd6..ddc03f57 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -411,6 +411,12 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) page = pfn_to_page(pfn+pix); if (!page_count(page)) { get_page(page); + /* + * TODO: + * The pages which get_page() has been called with + * should be recorded. Because these pages have to + * be passed to put_page() before they are freed. + */ } error = vm_insert_page(vma, rva+(pix*PAGE_SIZE), page); if (error) {