From 7e342751a2cb40c393454f8ccc4a26f26f929d5b Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Fri, 7 Sep 2018 14:28:23 +0900 Subject: [PATCH] do_syscall: Delegate system calls to the mcexec with the same pid This includes the following fix: send_syscall, do_syscall: remove argument pid Fujitsu: POSTK_TEMP_FIX_26 Refs: #1165 Change-Id: I702362c07a28f507a5e43dd751949aefa24bc8c0 --- arch/x86_64/kernel/syscall.c | 3 +- executer/include/uprotocol.h | 6 ++ executer/kernel/mcctrl/control.c | 13 ++- executer/kernel/mcctrl/mcctrl.h | 1 + executer/kernel/mcctrl/syscall.c | 22 +--- executer/user/mcexec.c | 15 ++- kernel/include/syscall.h | 4 +- kernel/mem.c | 2 +- kernel/syscall.c | 173 +++++++------------------------ kernel/xpmem.c | 2 +- test/issues/1165/C1165.sh | 139 +++++++++++++++++++++++++ test/issues/1165/C1165.txt | 72 +++++++++++++ test/issues/1165/C1165T01.c | 97 +++++++++++++++++ test/issues/1165/Makefile | 13 +++ test/issues/1165/README | 53 ++++++++++ 15 files changed, 445 insertions(+), 170 deletions(-) create mode 100644 test/issues/1165/C1165.sh create mode 100644 test/issues/1165/C1165.txt create mode 100644 test/issues/1165/C1165T01.c create mode 100644 test/issues/1165/Makefile create mode 100644 test/issues/1165/README diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c index d60ae4c7..9aa02d67 100644 --- a/arch/x86_64/kernel/syscall.c +++ b/arch/x86_64/kernel/syscall.c @@ -2698,8 +2698,7 @@ time_t time(void) { else { sreq.number = __NR_time; sreq.args[0] = (uintptr_t)NULL; - ret = (time_t)do_syscall(&sreq, ihk_mc_get_processor_id(), - thread->proc->pid); + ret = (time_t)do_syscall(&sreq, ihk_mc_get_processor_id()); } return ret; diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 51a6e799..c21353af 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -263,6 +263,12 @@ struct terminate_thread_desc { unsigned long tsk; /* struct task_struct * */ }; +struct rpgtable_desc { + uintptr_t rpgtable; + uintptr_t start; + uintptr_t len; +}; + enum perf_ctrl_type { PERF_CTRL_SET, PERF_CTRL_GET, diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 7a2bd855..e6090e76 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -1755,7 +1755,7 @@ mcexec_getcredv(int __user *virt) return 0; } -int mcexec_create_per_process_data(ihk_os_t os) +int mcexec_create_per_process_data(ihk_os_t os, struct rpgtable_desc *rpt) { struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct mcctrl_per_proc_data *ppd = NULL; @@ -1812,6 +1812,11 @@ int mcexec_create_per_process_data(ihk_os_t os) dprintk("%s: PID: %d, counter: %d\n", __FUNCTION__, ppd->pid, atomic_read(&ppd->refcount)); + if (rpt) { + ppd->rpgtable = rpt->rpgtable; + return mcctrl_clear_pte_range(rpt->start, rpt->len); + } + return 0; } @@ -2638,7 +2643,8 @@ static long mcexec_release_user_space(struct release_user_space_desc *__user arg } #if 1 - return clear_pte_range(desc.user_start, desc.user_end - desc.user_start); + return mcctrl_clear_pte_range(desc.user_start, + desc.user_end - desc.user_start); #else return release_user_space(desc.user_start, desc.user_end - desc.user_start); #endif @@ -3157,7 +3163,8 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, return mcexec_get_cpu(os); case MCEXEC_UP_CREATE_PPD: - return mcexec_create_per_process_data(os); + return mcexec_create_per_process_data(os, + (struct rpgtable_desc *)arg); case MCEXEC_UP_GET_NODES: return mcexec_get_nodes(os); diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index 651263eb..2ead9c23 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -486,6 +486,7 @@ inline struct mcctrl_per_thread_data *mcctrl_get_per_thread_data(struct mcctrl_p #else /* POSTK_DEBUG_ARCH_DEP_56 */ inline struct mcctrl_per_thread_data *mcctrl_get_per_thread_data(struct mcctrl_per_proc_data *ppd, struct task_struct *task); #endif /* POSTK_DEBUG_ARCH_DEP_56 */ +int mcctrl_clear_pte_range(uintptr_t start, uintptr_t len); void __return_syscall(ihk_os_t os, struct ikc_scd_packet *packet, long ret, int stid); diff --git a/executer/kernel/mcctrl/syscall.c b/executer/kernel/mcctrl/syscall.c index a8bbb60b..f193bbd8 100644 --- a/executer/kernel/mcctrl/syscall.c +++ b/executer/kernel/mcctrl/syscall.c @@ -2109,7 +2109,7 @@ out: return (IS_ERR_VALUE(map))? (int)map: 0; } -int clear_pte_range(uintptr_t start, uintptr_t len) +int mcctrl_clear_pte_range(uintptr_t start, uintptr_t len) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -2356,25 +2356,7 @@ int __do_in_kernel_syscall(ihk_os_t os, struct ikc_scd_packet *packet) break; case __NR_munmap: - /* Set new remote page table if not zero */ - if (sc->args[2]) { - struct mcctrl_per_proc_data *ppd = NULL; - - ppd = mcctrl_get_per_proc_data(usrdata, sc->args[3]); - if (unlikely(!ppd)) { - kprintf("%s: ERROR: no per-process structure for PID %d??\n", - __FUNCTION__, task_tgid_vnr(current)); - return -1; - } - - ppd->rpgtable = sc->args[2]; - - dprintk("%s: pid: %d, rpgtable: 0x%lx updated\n", - __FUNCTION__, ppd->pid, ppd->rpgtable); - mcctrl_put_per_proc_data(ppd); - } - - ret = clear_pte_range(sc->args[0], sc->args[1]); + ret = mcctrl_clear_pte_range(sc->args[0], sc->args[1]); break; case __NR_mprotect: diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 0fc7892a..d02b5cdc 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -2510,7 +2510,7 @@ int main(int argc, char **argv) } /* Register per-process structure in mcctrl */ - if (ioctl(fd, MCEXEC_UP_CREATE_PPD) != 0) { + if (ioctl(fd, MCEXEC_UP_CREATE_PPD, NULL)) { perror("creating mcctrl per-process structure"); close(fd); exit(1); @@ -2872,7 +2872,8 @@ out: static struct uti_desc *uti_desc; -static void kill_thread(unsigned long tid, int sig) +static void kill_thread(unsigned long tid, int sig, + struct thread_data_s *my_thread) { struct thread_data_s *tp; @@ -2880,6 +2881,8 @@ static void kill_thread(unsigned long tid, int sig) sig = LOCALSIG; for (tp = thread_data; tp; tp = tp->next) { + if (tp == my_thread) + continue; if (tp->remote_tid == tid) { if (pthread_kill(tp->thread_id, sig) == ESRCH) { printf("%s: ERROR: Thread not found (tid=%ld,sig=%d)\n", __FUNCTION__, tid, sig); @@ -3272,7 +3275,7 @@ int main_loop(struct thread_data_s *my_thread) break; case __NR_kill: // interrupt syscall - kill_thread(w.sr.args[1], w.sr.args[2]); + kill_thread(w.sr.args[1], w.sr.args[2], my_thread); do_syscall_return(fd, cpu, 0, 0, 0, 0, 0); break; case __NR_exit: @@ -3452,6 +3455,7 @@ gettid_out: case 0: { int ret = 1; struct newprocess_desc npdesc; + struct rpgtable_desc rpt; ischild = 1; /* Reopen device fd */ @@ -3464,7 +3468,10 @@ gettid_out: goto fork_child_sync_pipe; } - if (ioctl(fd, MCEXEC_UP_CREATE_PPD) != 0) { + rpt.start = w.sr.args[1]; + rpt.len = w.sr.args[2]; + rpt.rpgtable = w.sr.args[3]; + if (ioctl(fd, MCEXEC_UP_CREATE_PPD, &rpt)) { fs->status = -errno; fprintf(stderr, "ERROR: creating PPD %s\n", dev); diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index cdf7cd96..adaeb65f 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -348,9 +348,9 @@ struct syscall_post { SYSCALL_ARG_##a2(2); SYSCALL_ARG_##a3(3); \ SYSCALL_ARG_##a4(4); SYSCALL_ARG_##a5(5); -#define SYSCALL_FOOTER return do_syscall(&request, ihk_mc_get_processor_id(), 0) +#define SYSCALL_FOOTER return do_syscall(&request, ihk_mc_get_processor_id()) -extern long do_syscall(struct syscall_request *req, int cpu, int pid); +extern long do_syscall(struct syscall_request *req, int cpu); int obtain_clone_cpuid(cpu_set_t *cpu_set, int use_last); extern long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx); diff --git a/kernel/mem.c b/kernel/mem.c index f6ec0ca8..14f6dad0 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -993,7 +993,7 @@ void coredump(struct thread *thread, void *regs) request.args[0] = chunks; request.args[1] = virt_to_phys(coretable); /* no data for now */ - ret = do_syscall(&request, thread->cpu_id, thread->proc->pid); + ret = do_syscall(&request, thread->cpu_id); if (ret == 0) { kprintf("dumped core.\n"); } else { diff --git a/kernel/syscall.c b/kernel/syscall.c index 83c57453..e2190cf5 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -148,24 +148,13 @@ long (*linux_wait_event)(void *_resp, unsigned long nsec_timeout); int (*linux_printk)(const char *fmt, ...); int (*linux_clock_gettime)(clockid_t clk_id, struct timespec *tp); -static void send_syscall(struct syscall_request *req, int cpu, int pid, struct syscall_response *res) +static void send_syscall(struct syscall_request *req, int cpu, + struct syscall_response *res) { struct ikc_scd_packet packet IHK_DMA_ALIGN; struct ihk_ikc_channel_desc *syscall_channel = get_cpu_local_var(cpu)->ikc2linux; int ret; - if(req->number == __NR_exit_group || - req->number == __NR_kill){ // interrupt syscall -#ifndef POSTK_DEBUG_TEMP_FIX_26 /* do_syscall arg pid is not targetpid */ - if (req->number == __NR_kill) { - req->rtid = -1; // no response - pid = req->args[0]; - } - if (req->number == __NR_gettid) - pid = req->args[1]; -#endif /* !POSTK_DEBUG_TEMP_FIX_26 */ - } - res->status = 0; req->valid = 0; @@ -177,11 +166,7 @@ static void send_syscall(struct syscall_request *req, int cpu, int pid, struct s #ifdef SYSCALL_BY_IKC packet.msg = SCD_MSG_SYSCALL_ONESIDE; packet.ref = cpu; -#ifdef POSTK_DEBUG_TEMP_FIX_26 /* do_syscall arg pid is not targetpid */ - packet.pid = pid; -#else /* POSTK_DEBUG_TEMP_FIX_26 */ - packet.pid = pid ? pid : cpu_local_var(current)->proc->pid; -#endif /* POSTK_DEBUG_TEMP_FIX_26 */ + packet.pid = cpu_local_var(current)->proc->pid; packet.resp_pa = virt_to_phys(res); dkprintf("send syscall, nr: %d, pid: %d\n", req->number, packet.pid); @@ -192,7 +177,7 @@ static void send_syscall(struct syscall_request *req, int cpu, int pid, struct s #endif } -long do_syscall(struct syscall_request *req, int cpu, int pid) +long do_syscall(struct syscall_request *req, int cpu) { struct syscall_response res; struct syscall_request req2 IHK_DMA_ALIGN; @@ -211,9 +196,6 @@ long do_syscall(struct syscall_request *req, int cpu, int pid) t_s = rdtsc(); } #endif // PROFILE_ENABLE -#ifdef POSTK_DEBUG_TEMP_FIX_26 /* do_syscall arg pid is not targetpid */ - int target_pid = pid; -#endif /* POSTK_DEBUG_TEMP_FIX_26 */ dkprintf("SC(%d)[%3d] sending syscall\n", ihk_mc_get_processor_id(), @@ -224,52 +206,10 @@ long do_syscall(struct syscall_request *req, int cpu, int pid) barrier(); -#ifdef POSTK_DEBUG_TEMP_FIX_26 /* do_syscall arg pid is not targetpid */ - switch (req->number) { - case __NR_kill: - req->rtid = -1; // no response - target_pid = req->args[0]; - break; - case __NR_gettid: - target_pid = req->args[1]; - break; - default: - break; - } - target_pid = target_pid ? target_pid : proc->pid; -#endif /* POSTK_DEBUG_TEMP_FIX_26 */ - if(req->number != __NR_exit_group){ -#ifdef POSTK_DEBUG_TEMP_FIX_26 /* do_syscall arg pid is not targetpid */ -#ifdef POSTK_DEBUG_TEMP_FIX_48 /* nohost flag missed fix */ - struct process *target_proc = NULL; - struct mcs_rwlock_node_irqsave lock; - - if (target_pid != proc->pid) { - target_proc = find_process(target_pid, &lock); - if (!target_proc) { - return -EPIPE; - } - process_unlock(target_proc, &lock); - } else { - target_proc = proc; - } - - if (target_proc->nohost) { // host is down + if (proc->nohost) {// host is down return -EPIPE; } -#else /* POSTK_DEBUG_TEMP_FIX_48 */ - if (proc->nohost && // host is down - target_pid == proc->pid) { - return -EPIPE; - } -#endif /* POSTK_DEBUG_TEMP_FIX_48 */ -#else /* POSTK_DEBUG_TEMP_FIX_26 */ - if(proc->nohost && // host is down - pid == proc->pid) { - return -EPIPE; - } -#endif /* POSTK_DEBUG_TEMP_FIX_26 */ ++thread->in_syscall_offload; } @@ -289,11 +229,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid) req->ttid = 0; } res.req_thread_status = IHK_SCD_REQ_THREAD_SPINNING; -#ifdef POSTK_DEBUG_TEMP_FIX_26 /* do_syscall arg pid is not targetpid */ - send_syscall(req, cpu, target_pid, &res); -#else /* POSTK_DEBUG_TEMP_FIX_26 */ - send_syscall(req, cpu, pid, &res); -#endif /* POSTK_DEBUG_TEMP_FIX_26 */ + send_syscall(req, cpu, &res); if (req->rtid == -1) { preempt_disable(); @@ -387,11 +323,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid) req2.ttid = res.stid; res.req_thread_status = IHK_SCD_REQ_THREAD_SPINNING; -#ifdef POSTK_DEBUG_TEMP_FIX_26 /* do_syscall arg pid is not targetpid */ - send_syscall(&req2, cpu, target_pid, &res); -#else /* POSTK_DEBUG_TEMP_FIX_26 */ - send_syscall(&req2, cpu, pid, &res); -#endif /* POSTK_DEBUG_TEMP_FIX_26 */ + send_syscall(&req2, cpu, &res); #ifdef PROFILE_ENABLE profile_event_add(PROFILE_remote_page_fault, (rdtsc() - t_s)); @@ -463,7 +395,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid) req2.ttid = res.stid; res.req_thread_status = IHK_SCD_REQ_THREAD_SPINNING; - send_syscall(&req2, cpu, pid, &res); + send_syscall(&req2, cpu, &res); } } if (req->rtid == -1) { @@ -514,7 +446,6 @@ long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx) static int wait_zombie(struct thread *thread, struct process *child, int *status, int options) { int ret; struct syscall_request request IHK_DMA_ALIGN; - int ppid = 0; dkprintf("wait_zombie,found PS_ZOMBIE process: %d\n", child->pid); @@ -522,7 +453,6 @@ static int wait_zombie(struct thread *thread, struct process *child, int *status *status = child->exit_status; } - ppid = child->ppid_parent->pid; if(child->ppid_parent->pid != thread->proc->pid || child->nowait) return child->pid; request.number = __NR_wait4; @@ -530,7 +460,7 @@ static int wait_zombie(struct thread *thread, struct process *child, int *status request.args[1] = 0; request.args[2] = options; /* Ask host to clean up exited child */ - ret = do_syscall(&request, ihk_mc_get_processor_id(), ppid); + ret = do_syscall(&request, ihk_mc_get_processor_id()); if (ret != child->pid) kprintf("WARNING: host waitpid failed?\n"); @@ -980,7 +910,7 @@ void terminate_mcexec(int rc, int sig) request.number = __NR_exit_group; request.args[0] = proc->exit_status; proc->nohost = 1; - do_syscall(&request, ihk_mc_get_processor_id(), proc->pid); + do_syscall(&request, ihk_mc_get_processor_id()); } } @@ -2029,8 +1959,7 @@ static void settid(struct thread *thread, int nr_tids, int *tids) */ request.args[4] = nr_tids; request.args[5] = virt_to_phys(tids); - if ((ret = do_syscall(&request, ihk_mc_get_processor_id(), - thread->proc->pid)) < 0) { + if ((ret = do_syscall(&request, ihk_mc_get_processor_id())) < 0) { kprintf("%s: WARNING: do_syscall returns %d\n", __FUNCTION__, ret); } @@ -2246,7 +2175,7 @@ SYSCALL_DECLARE(execve) request.args[0] = 1; /* 1st phase - get ELF desc */ request.args[1] = (unsigned long)filename; request.args[2] = virt_to_phys(desc); - ret = do_syscall(&request, ihk_mc_get_processor_id(), 0); + ret = do_syscall(&request, ihk_mc_get_processor_id()); if (ret != 0) { dkprintf("execve(): ERROR: host failed to load elf header, errno: %d\n", @@ -2329,7 +2258,7 @@ SYSCALL_DECLARE(execve) request.args[2] = sizeof(struct program_load_desc) + sizeof(struct program_image_section) * desc->num_sections; - if ((ret = do_syscall(&request, ihk_mc_get_processor_id(), 0)) != 0) { + if ((ret = do_syscall(&request, ihk_mc_get_processor_id())) != 0) { goto end; } @@ -2543,11 +2472,16 @@ retry_tid: else { request1.number = __NR_clone; request1.args[0] = 0; + request1.args[1] = new->vm->region.user_start; + request1.args[2] = new->vm->region.user_end - + new->vm->region.user_start; + request1.args[3] = + virt_to_phys(new->vm->address_space->page_table); if(clone_flags & CLONE_PARENT){ if(oldproc->ppid_parent->pid != 1) request1.args[0] = clone_flags; } - newproc->pid = do_syscall(&request1, ihk_mc_get_processor_id(), 0); + newproc->pid = do_syscall(&request1, ihk_mc_get_processor_id()); if (newproc->pid < 0) { kprintf("ERROR: forking host process\n"); @@ -2561,24 +2495,6 @@ retry_tid: new->vm->address_space->pids[0] = new->proc->pid; dkprintf("fork(): new pid: %d\n", new->proc->pid); -#ifndef POSTK_DEBUG_TEMP_FIX_48 /* nohost flag missed fix */ - /* clear user space PTEs and set new rpgtable so that consequent - * page faults will look up the right mappings */ - request1.number = __NR_munmap; - request1.args[0] = new->vm->region.user_start; - request1.args[1] = new->vm->region.user_end - - new->vm->region.user_start; - /* 3rd parameter denotes new rpgtable of host process */ - request1.args[2] = virt_to_phys(new->vm->address_space->page_table); - request1.args[3] = newproc->pid; - - dkprintf("fork(): requesting PTE clear and rpgtable (0x%lx) update\n", - request1.args[2]); - - if (do_syscall(&request1, ihk_mc_get_processor_id(), new->proc->pid)) { - kprintf("ERROR: clearing PTEs in host process\n"); - } -#endif /* !POSTK_DEBUG_TEMP_FIX_48 */ if(oldproc->monitoring_event && oldproc->monitoring_event->attr.inherit){ newproc->monitoring_event = oldproc->monitoring_event; @@ -2672,24 +2588,6 @@ retry_tid: chain_process(newproc); } -#ifdef POSTK_DEBUG_TEMP_FIX_48 /* nohost flag missed fix */ - /* clear user space PTEs and set new rpgtable so that consequent - * page faults will look up the right mappings */ - request1.number = __NR_munmap; - request1.args[0] = new->vm->region.user_start; - request1.args[1] = new->vm->region.user_end - - new->vm->region.user_start; - /* 3rd parameter denotes new rpgtable of host process */ - request1.args[2] = virt_to_phys(new->vm->address_space->page_table); - request1.args[3] = newproc->pid; - - dkprintf("fork(): requesting PTE clear and rpgtable (0x%lx) update\n", - request1.args[2]); - - if (do_syscall(&request1, ihk_mc_get_processor_id(), new->proc->pid)) { - kprintf("ERROR: clearing PTEs in host process\n"); - } -#endif /* !POSTK_DEBUG_TEMP_FIX_48 */ if (oldproc->ptrace) { ptrace_event = ptrace_check_clone_event(old, clone_flags); if (ptrace_event) { @@ -2706,7 +2604,7 @@ retry_tid: request1.number = __NR_clone; request1.args[0] = 1; request1.args[1] = new->tid; - do_syscall(&request1, ihk_mc_get_processor_id(), 0); + do_syscall(&request1, ihk_mc_get_processor_id()); } runq_add_thread(new, cpuid); @@ -2846,7 +2744,7 @@ getcred(int *_buf) request.number = __NR_setfsuid; request.args[0] = phys; request.args[1] = 1; - do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_syscall(&request, ihk_mc_get_processor_id()); return buf; } @@ -2953,7 +2851,7 @@ SYSCALL_DECLARE(setfsuid) request.number = __NR_setfsuid; request.args[0] = fsuid; request.args[1] = 0; - newfsuid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + newfsuid = do_syscall(&request, ihk_mc_get_processor_id()); #ifdef POSTK_DEBUG_TEMP_FIX_45 /* setfsgid()/setfsuid() mismatch fix. */ do_setresuid((int)(newfsuid >> 32)); newfsuid &= (1UL << 32) - 1; @@ -3016,7 +2914,7 @@ SYSCALL_DECLARE(setfsgid) request.number = __NR_setfsgid; request.args[0] = fsgid; - newfsgid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + newfsgid = do_syscall(&request, ihk_mc_get_processor_id()); #ifdef POSTK_DEBUG_TEMP_FIX_45 /* setfsgid()/setfsuid() mismatch fix. */ do_setresgid((int)(newfsgid >> 32)); newfsgid &= (1UL << 32) - 1; @@ -3469,7 +3367,7 @@ SYSCALL_DECLARE(signalfd4) request.number = __NR_signalfd4; request.args[0] = 0; request.args[1] = flags; - fd = do_syscall(&request, ihk_mc_get_processor_id(), 0); + fd = do_syscall(&request, ihk_mc_get_processor_id()); if(fd < 0){ return fd; } @@ -4030,7 +3928,7 @@ SYSCALL_DECLARE(perf_event_open) request.number = __NR_perf_event_open; request.args[0] = 0; - fd = do_syscall(&request, ihk_mc_get_processor_id(), 0); + fd = do_syscall(&request, ihk_mc_get_processor_id()); if(fd < 0){ return fd; } @@ -5476,7 +5374,8 @@ long do_futex(int n, unsigned long arg0, unsigned long arg1, request.args[1] = (flags & FUTEX_CLOCK_REALTIME)? CLOCK_REALTIME: CLOCK_MONOTONIC; - int r = do_syscall(&request, ihk_mc_get_processor_id(), 0); + int r = do_syscall(&request, + ihk_mc_get_processor_id()); if (r < 0) { return -EFAULT; @@ -6592,7 +6491,7 @@ SYSCALL_DECLARE(sched_setparam) request1.args[0] = SCHED_CHECK_SAME_OWNER; request1.args[1] = pid; - retval = do_syscall(&request1, ihk_mc_get_processor_id(), 0); + retval = do_syscall(&request1, ihk_mc_get_processor_id()); if (retval != 0) { return retval; } @@ -6673,7 +6572,7 @@ SYSCALL_DECLARE(sched_setscheduler) request1.number = __NR_sched_setparam; request1.args[0] = SCHED_CHECK_ROOT; - retval = do_syscall(&request1, ihk_mc_get_processor_id(), 0); + retval = do_syscall(&request1, ihk_mc_get_processor_id()); if (retval != 0) { return retval; } @@ -6699,7 +6598,7 @@ SYSCALL_DECLARE(sched_setscheduler) request1.args[0] = SCHED_CHECK_SAME_OWNER; request1.args[1] = pid; - retval = do_syscall(&request1, ihk_mc_get_processor_id(), 0); + retval = do_syscall(&request1, ihk_mc_get_processor_id()); if (retval != 0) { return retval; } @@ -7014,7 +6913,7 @@ SYSCALL_DECLARE(setitimer) request.args[1] = ihk_mc_syscall_arg1(ctx); request.args[2] = ihk_mc_syscall_arg2(ctx); - return do_syscall(&request, ihk_mc_get_processor_id(), 0); + return do_syscall(&request, ihk_mc_get_processor_id()); } else if(which == ITIMER_VIRTUAL){ if(old){ @@ -7086,7 +6985,7 @@ SYSCALL_DECLARE(getitimer) request.args[0] = ihk_mc_syscall_arg0(ctx); request.args[1] = ihk_mc_syscall_arg1(ctx); - return do_syscall(&request, ihk_mc_get_processor_id(), 0); + return do_syscall(&request, ihk_mc_get_processor_id()); } else if(which == ITIMER_VIRTUAL){ if(old){ @@ -7182,7 +7081,7 @@ SYSCALL_DECLARE(clock_gettime) request.args[0] = ihk_mc_syscall_arg0(ctx); request.args[1] = ihk_mc_syscall_arg1(ctx); - return do_syscall(&request, ihk_mc_get_processor_id(), 0); + return do_syscall(&request, ihk_mc_get_processor_id()); } SYSCALL_DECLARE(gettimeofday) @@ -7217,7 +7116,7 @@ SYSCALL_DECLARE(gettimeofday) request.args[0] = (unsigned long)tv; request.args[1] = (unsigned long)tz; - return do_syscall(&request, ihk_mc_get_processor_id(), 0); + return do_syscall(&request, ihk_mc_get_processor_id()); } SYSCALL_DECLARE(settimeofday) @@ -7337,7 +7236,7 @@ SYSCALL_DECLARE(nanosleep) request.args[0] = (unsigned long)tv; request.args[1] = (unsigned long)rem; - return do_syscall(&request, ihk_mc_get_processor_id(), 0); + return do_syscall(&request, ihk_mc_get_processor_id()); } //#define DISABLE_SCHED_YIELD @@ -9172,7 +9071,7 @@ int util_thread(struct uti_attr *arg) request.args[3] = (unsigned long)uti_clv; request.args[4] = uti_desc; thread->uti_state = UTI_STATE_RUNNING_IN_LINUX; - rc = do_syscall(&request, ihk_mc_get_processor_id(), 0); + rc = do_syscall(&request, ihk_mc_get_processor_id()); dkprintf("%s: returned from do_syscall,tid=%d,rc=%lx\n", __FUNCTION__, thread->tid, rc); thread->uti_state = UTI_STATE_EPILOGUE; diff --git a/kernel/xpmem.c b/kernel/xpmem.c index 5b633426..8419409d 100644 --- a/kernel/xpmem.c +++ b/kernel/xpmem.c @@ -83,7 +83,7 @@ int xpmem_open( request.number = __NR_open; request.args[0] = (unsigned long)pathname; request.args[1] = flags; - fd = do_syscall(&request, ihk_mc_get_processor_id(), 0); + fd = do_syscall(&request, ihk_mc_get_processor_id()); if (fd < 0) { XPMEM_DEBUG("__NR_open error: fd=%d", fd); return fd; diff --git a/test/issues/1165/C1165.sh b/test/issues/1165/C1165.sh new file mode 100644 index 00000000..002a99aa --- /dev/null +++ b/test/issues/1165/C1165.sh @@ -0,0 +1,139 @@ +#!/bin/sh +BOOTPARAM="-c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1" +USELTP=1 +USEOSTEST=1 + +################################################################################ +BINDIR= +SBINDIR= +OSTESTDIR= +LTPDIR= +LTPBIN= +MCEXEC= +TESTMCK= + +if [ -f $HOME/mck_test_config ]; then + . $HOME/mck_test_config +elif [ -f ../../../mck_test_config.sample ]; then + . ../../../mck_test_config.sample +else + BIN= + SBIN= + OSTEST= + LTP= +fi + +#------------------------------------------------------------------------------- +if [ "x$BIN" = x ]; then + if [ -f ../../../config.h ]; then + str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'` + eval $str + fi +else + BINDIR="$BIN" +fi + +if [ "x$SBIN" = x ]; then + if [ -f ../../../Makefile ]; then + str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'` + eval $str + fi +else + SBINDIR="$SBIN" +fi + +if [ ! -x "$BINDIR/mcexec" ]; then + echo no mckernel found $BINDIR >&2 + exit 1 +fi +MCEXEC="$BINDIR/mcexec" + +#------------------------------------------------------------------------------- +if [ "x$USELTP" != x ]; then + if [ "x$LTP" = x ]; then + if [ -f "$HOME/ltp/testcases/bin/fork01" ]; then + LTPDIR="$HOME/ltp" + fi + else + LTPDIR="$LTP" + fi + + if [ ! -x "$LTPDIR/testcases/bin/fork01" ]; then + echo no LTP found $LTPDIR >&2 + exit 1 + fi + LTPBIN="$LTPDIR/testcases/bin" +fi + +#------------------------------------------------------------------------------- +if [ "x$USEOSTEST" != x ]; then + if [ "x$OSTEST" = x ]; then + if [ -f "$HOME/ostest/bin/test_mck" ]; then + OSTESTDIR="$HOME/ostest" + fi + else + OSTESTDIR="$OSTEST" + fi + + if [ ! -x "$OSTESTDIR"/bin/test_mck ]; then + echo no ostest found $OSTESTDIR >&2 + exit 1 + fi + TESTMCK="$OSTESTDIR/bin/test_mck" +fi + +#=============================================================================== +if [ ! -x "$SBINDIR/mcstop+release.sh" ]; then + echo mcstop+release: not found >&2 + exit 1 +fi +echo -n "mcstop+release.sh ... " +sudo "$SBINDIR/mcstop+release.sh" +echo "done" + +if lsmod | grep mcctrl > /dev/null 2>&1; then + echo mckernel shutdown failed >&2 + exit 1 +fi + +if [ ! -x "$SBINDIR/mcreboot.sh" ]; then + echo mcreboot: not found >&2 + exit 1 +fi +echo -n "mcreboot.sh $BOOTPARAM ... " +sudo "$SBINDIR/mcreboot.sh" $BOOTPARAM +echo "done" + +if ! lsmod | grep mcctrl > /dev/null 2>&1; then + echo mckernel boot failed >&2 + exit 1 +fi + +################################################################################ +$MCEXEC ./C1165T01 + +sudo sh "$OSTESTDIR"/util/rmmod_test_drv.sh > /dev/null 2>&1 +sudo sh "$OSTESTDIR"/util/insmod_test_drv.sh +echo a > mmapfile +sudo timeout -s 9 3 $MCEXEC "$TESTMCK" -s force_exit -n 0 -- -d /dev/test_mck/mmap_dev -f mmapfile +rm -f mmapfile +sudo sh "$OSTESTDIR"/util/rmmod_test_drv.sh +"$SBINDIR"/ihkosctl 0 clear_kmsg +"$SBINDIR"/ihkosctl 0 ioctl 40000000 1 +"$SBINDIR"/ihkosctl 0 ioctl 40000000 2 +"$SBINDIR"/ihkosctl 0 kmsg | sed 's/[^:]*://' | awk '$2 == "processes" {p = $1} $2 == "threads" {t = $1}END{if (p != 0 || t != 0) {print "*** C1165T02 NG"} else {print "*** C1165T02 OK"}}' + +for i in clone01:03 clone03:04 clone04:05 clone06:06 clone07:07 fork01:08 \ + fork02:09 fork03:10 fork04:11 fork07:12 fork08:13 fork09:14 \ + fork10:15; do + tp=`echo $i|sed 's/:.*//'` + id=`echo $i|sed 's/.*://'` + sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt + ok=`grep TPASS $tp.txt | wc -l` + ng=`grep TFAIL $tp.txt | wc -l` + if [ $ng = 0 ]; then + echo "*** C1165T$id: $tp OK ($ok)" + else + echo "*** C1165T$id: $tp NG (ok=$ok ng=%ng)" + fi +done diff --git a/test/issues/1165/C1165.txt b/test/issues/1165/C1165.txt new file mode 100644 index 00000000..e0549ddf --- /dev/null +++ b/test/issues/1165/C1165.txt @@ -0,0 +1,72 @@ +Script started on Tue Aug 28 13:52:33 2018 +bash-4.2$ make test +sh ./C1165.sh +mcstop+release.sh ... done +mcreboot.sh -c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1 ... done +*** C1165T01 OK +insmod /home/shirasawa/ostest/util/../bin/test_mck.ko +create charcter device /dev/test_mck/mmap_dev(240:0) +create charcter device /dev/test_mck/mmap_dev2(240:1) +TEST_SUITE: force_exit +TEST_NUMBER: 0 +ARGS: -d /dev/test_mck/mmap_dev -f mmapfile +read 1 byte (a(97)) +mmap(0x2aaaac73b000) +remove /dev/test_mck +rmmod /home/shirasawa/ostest/util/../bin/test_mck.ko +*** C1165T02 OK +clone01 1 TPASS : clone returned 9933 +*** C1165T03: clone01 OK (1) +clone03 1 TPASS : Test passed +*** C1165T04: clone03 OK (1) +clone04 1 TPASS : expected failure; Got EINVAL +*** C1165T05: clone04 OK (1) +clone06 1 TPASS : Test Passed +*** C1165T06: clone06 OK (1) +clone07 1 TPASS : Use of return() in child did not cause SIGSEGV +*** C1165T07: clone07 OK (1) +fork01 1 TPASS : fork() returned 10278 +fork01 2 TPASS : child pid and fork() return agree: 10278 +*** C1165T08: fork01 OK (2) +fork02 0 TINFO : Inside parent +fork02 0 TINFO : Inside child +fork02 0 TINFO : exit status of wait 0 +fork02 1 TPASS : test 1 PASSED +*** C1165T09: fork02 OK (1) +fork03 0 TINFO : process id in parent of child from fork : 10428 +fork03 1 TPASS : test 1 PASSED +*** C1165T10: fork03 OK (1) +fork04 1 TPASS : Env var TERM unchanged after fork(): xterm +fork04 2 TPASS : Env var NoTSetzWq unchanged after fork(): getenv() does not find variable set +fork04 3 TPASS : Env var TESTPROG unchanged after fork(): FRKTCS04 +*** C1165T11: fork04 OK (3) +fork07 0 TINFO : Forking 100 children +fork07 0 TINFO : Forked all 100 children, now collecting +fork07 0 TINFO : Collected all 100 children +fork07 1 TPASS : 100/100 children read correctly from an inheritted fd +*** C1165T12: fork07 OK (1) +fork08 0 TINFO : parent forksval: 1 +fork08 0 TINFO : parent forksval: 2 +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 1 TPASS : parent test PASSED +fork08 0 TINFO : second child got char: b +fork08 1 TPASS : Test passed in childnumber 2 +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 2 TPASS : parent test PASSED +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 3 TPASS : parent test PASSED +fork08 0 TINFO : Number of processes forked is 2 +*** C1165T13: fork08 OK (4) +fork09 0 TINFO : OPEN_MAX is 1024 +fork09 0 TINFO : first file descriptor is 12 +fork09 0 TINFO : Parent reporting 1023 files open +fork09 0 TINFO : Child opened new file #1023 +fork09 1 TPASS : test 1 PASSED +*** C1165T14: fork09 OK (1) +fork10 0 TINFO : fork child A +fork10 1 TPASS : test 1 PASSED +*** C1165T15: fork10 OK (1) +bash-4.2$ exit +exit + +Script done on Tue Aug 28 13:53:01 2018 diff --git a/test/issues/1165/C1165T01.c b/test/issues/1165/C1165T01.c new file mode 100644 index 00000000..dc973d51 --- /dev/null +++ b/test/issues/1165/C1165T01.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + pid_t pid; + char buf[1024]; + int fd; + int rc; + int st; + int i; + + fd = open("/dev/zero", O_RDONLY); + if (fd < 0) { + perror("open"); + goto err; + } + if ((rc = read(fd, buf, 1024)) != 1024) { + if (rc < 0) { + perror("read"); + } + else if (rc == 0) { + fprintf(stderr, "EOF\n"); + } + else { + fprintf(stderr, "read too short %d\n", rc); + } + goto err; + } + close(fd); + + for (i = 0; i < 1024; i++) + buf[i] = 0x55; + + pid = fork(); + if (!pid) { + for (i = 0; i < 1024; i++) + if (buf[i] != 0x55) { + exit(2); + } + fd = open("/dev/zero", O_RDONLY); + if (fd < 0) { + perror("open"); + exit(1); + } + if ((rc = read(fd, buf, 1024)) != 1024) { + exit(1); + } + close(fd); + for (i = 0; i < 1024; i++) + if (buf[i] != 0) { + exit(3); + } + exit(0); + } + + while (waitpid(pid, &st, 0) == -1 && errno == EINTR); + + if (!WIFEXITED(st)) { + fprintf(stderr, "child failed %08x\n", st); + goto err; + } + else if (WEXITSTATUS(st) != 0) { + if (WEXITSTATUS(st) == 1) { + fprintf(stderr, "child I/O error\n"); + } + else if (WEXITSTATUS(st) == 2) { + fprintf(stderr, "child memory error\n"); + } + else if (WEXITSTATUS(st) == 3) { + fprintf(stderr, "child read error\n"); + } + else { + fprintf(stderr, "child error %08x\n", st); + } + goto err; + } + + for (i = 0; i < 1024; i++) + if (buf[i] != 0x55) { + fprintf(stderr, "BAD value 0x%02x != 0x55\n", buf[i]); + goto err; + } + + fprintf(stderr, "*** C1165T01 OK\n"); + exit(0); +err: + fprintf(stderr, "*** C1165T01 NG\n"); + exit(1); +} diff --git a/test/issues/1165/Makefile b/test/issues/1165/Makefile new file mode 100644 index 00000000..b7193f36 --- /dev/null +++ b/test/issues/1165/Makefile @@ -0,0 +1,13 @@ +CC=gcc +TARGET=C1165T01 + +all:: $(TARGET) + +C1024T01: C1165T01.c + $(CC) -o C1165T01 C1165T01.c -Wall -g + +test:: $(TARGET) + sh ./C1165.sh + +clean:: + rm -f *.o $(TARGET) diff --git a/test/issues/1165/README b/test/issues/1165/README new file mode 100644 index 00000000..ad9b239e --- /dev/null +++ b/test/issues/1165/README @@ -0,0 +1,53 @@ +【Issue#1165 動作確認】 +□ テスト内容 +Issue#1165 で指摘されている現象は、以下の理由により既に解消されている。 +・ kill および gettid のシステムコールデリゲートは、McKernel と同一PIDを持つ + mcexec に対して発行するようになっているため、他プロセスの情報を参照する + ことは無い。 +・ 対応する mcexec が終了している状態でシステムコールデリゲートしたとしても、 + mcctrl が適切にエラーを返すため、指摘の現象が発生することは無い。 + +以上を踏まえ、Issue#1165 では、以下の改修を行った。 +・ 他 PID の mcexec にシステムコールデリゲートは発生しない (または解消可能) + ので、do_syscall と send_syscall のインタフェースから PID 指定を削除する。 +・ 他 PID の mcexec にシステムコールデリゲートする以下の処理は、同一 PID の + mcexec にシステムコールデリゲートするように変更する。 + - fork 後、親プロセスから子プロセスの mcexec に PTE の初期化を依頼する処理 + +このため、Issue#1165に対して以下のテストを行った。 +1. fork 後、子プロセスのシステムコールデリゲートで親プロセスの領域が破壊 + されないことを確認する。 +C1165T01 親プロセスが read 後 fork し、子プロセスが同じアドレスの領域に read + して子プロセスの領域が書き換えられ、親プロセスの領域が書き換えられ + ないことを確認する。 + +2. 指摘されたプログラムを実行し、残留プロセスが存在しないことを確認する。 +C1165T02 ostest force_exit + +3. LTP を用いて、変更が既存処理に影響しないことを確認する (以下の LTP が PASS + すること)。 +C1165T03 clone01 +C1165T04 clone03 +C1165T05 clone04 +C1165T06 clone06 +C1165T07 clone07 +C1165T08 fork01 +C1165T09 fork02 +C1165T10 fork03 +C1165T11 fork04 +C1165T12 fork07 +C1165T13 fork08 +C1165T14 fork09 +C1165T15 fork10 + +□ 実行手順 +$ make test + +実行できない場合は、C1165.shの以下の行を適切に書き換えた後に実行。 +BIN= mcexec が存在するパス +SBIN= mcreboot.sh が存在するパス +LTP= LTP が存在するパス + +□ 実行結果 +C1165.txt 参照。 +全ての項目が OK となっていることを確認。