From 781a69617bd37aece2e686a4d5fe615ff8e75818 Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Mon, 3 Sep 2018 18:20:00 +0900 Subject: [PATCH] uti: Replace data types represented as arrays with C structures Defining C structures for the following objects: (1) Remote and local context (2) Stack of system call arguments / return values Change-Id: Iafbb6c795bd765e3c78c54a255d8a1e4d4536288 --- executer/include/uprotocol.h | 26 ++++- executer/include/uti.h | 9 +- executer/kernel/mcctrl/arch/x86_64/archdeps.c | 8 ++ executer/kernel/mcctrl/control.c | 94 ++++++++-------- executer/kernel/mcctrl/driver.c | 4 +- executer/user/arch/x86_64/archdep.S | 28 +++-- executer/user/archdep.h | 4 +- executer/user/mcexec.c | 101 +++++------------- executer/user/syscall_intercept.c | 63 ++++++----- kernel/include/syscall.h | 9 ++ kernel/process.c | 2 +- kernel/syscall.c | 55 +++++----- 12 files changed, 215 insertions(+), 188 deletions(-) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 9430d5a4..3b3bd7f0 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -55,8 +55,8 @@ #define MCEXEC_UP_SYS_UMOUNT 0x30a02915 #define MCEXEC_UP_SYS_UNSHARE 0x30a02916 -#define MCEXEC_UP_UTIL_THREAD1 0x30a02920 -#define MCEXEC_UP_UTIL_THREAD2 0x30a02921 +#define MCEXEC_UP_UTI_GET_CTX 0x30a02920 +#define MCEXEC_UP_UTI_SAVE_FS 0x30a02921 #define MCEXEC_UP_SIG_THREAD 0x30a02922 #define MCEXEC_UP_SYSCALL_THREAD 0x30a02924 #define MCEXEC_UP_TERMINATE_THREAD 0x30a02925 @@ -331,4 +331,26 @@ struct uti_attr_desc { unsigned long phys_attr; }; +struct uti_ctx { + union { + char ctx[4096]; /* TODO: Get the size from config.h */ + struct { + int uti_refill_tid; + }; + }; +}; + +struct uti_get_ctx_desc { + unsigned long rp_rctx; /* Remote physical address of remote context */ + void *rctx; /* Remote context */ + void *lctx; /* Local context */ + int uti_refill_tid; + unsigned long key; /* OUT: struct task_struct* of mcexec thread, used to search struct host_thread */ +}; + +struct uti_save_fs_desc { + void *rctx; /* Remote context */ + void *lctx; /* Local context */ +}; + #endif diff --git a/executer/include/uti.h b/executer/include/uti.h index e542082b..05f7c7a1 100644 --- a/executer/include/uti.h +++ b/executer/include/uti.h @@ -8,17 +8,20 @@ struct syscall_struct { unsigned long uti_clv; /* copy of a clv in McKernel */ }; +#define UTI_SZ_SYSCALL_STACK 16 + /* Variables accessed by mcexec.c and syscall_intercept.c */ struct uti_desc { - void *wp; /* Syscall arguments list and record of McKernel context and Linux context */ + char lctx[4096]; /* TODO: Get the size from config.h */ + char rctx[4096]; /* TODO: Get the size from config.h */ int mck_tid; /* TODO: Move this out for multiple migrated-to-Linux threads */ unsigned long key; /* struct task_struct* of mcexec thread, used to search struct host_thread */ int pid, tid; /* Used as the id of tracee when issuing MCEXEC_UP_TERMINATE_THREAD */ unsigned long uti_clv; /* copy of McKernel clv */ int fd; /* /dev/mcosX */ - struct syscall_struct *syscall_param_top; /* stack-pointer of syscall arguments list */ - struct syscall_struct *syscall_param; /* TODO: make it auto variable */ + struct syscall_struct syscall_stack[UTI_SZ_SYSCALL_STACK]; /* stack of system call arguments and return values */ + int syscall_stack_top; /* stack-pointer of syscall arguments list */ long syscalls[512], syscalls2[512]; /* Syscall profile counters */ int start_syscall_intercept; /* Used to sync between mcexec.c and syscall_intercept.c */ }; diff --git a/executer/kernel/mcctrl/arch/x86_64/archdeps.c b/executer/kernel/mcctrl/arch/x86_64/archdeps.c index c33dd238..ff7a2b76 100644 --- a/executer/kernel/mcctrl/arch/x86_64/archdeps.c +++ b/executer/kernel/mcctrl/arch/x86_64/archdeps.c @@ -279,6 +279,14 @@ get_fs_ctx(void *ctx) return tctx->fs; } +unsigned long +get_rsp_ctx(void *ctx) +{ + struct trans_uctx *tctx = ctx; + + return tctx->rsp; +} + #ifdef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */ int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva, unsigned long *rpap, unsigned long *pgsizep) diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 4515939b..16127c62 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -1246,6 +1246,9 @@ int mcexec_syscall(struct mcctrl_usrdata *ud, struct ikc_scd_packet *packet) break; } } + if (!wqhln) { + dprintk("%s: uti: INFO: target worker (tid=%d) not found in wq_list\n", __FUNCTION__, packet->req.ttid); + } } else { if (!wqhln) { printk("%s: WARNING: no target thread (tid=%d) found for exact request??\n", @@ -2386,76 +2389,76 @@ extern void set_user_sp(unsigned long); extern void restore_fs(unsigned long fs); extern void save_fs_ctx(void *); extern unsigned long get_fs_ctx(void *); +extern unsigned long get_rsp_ctx(void *); -long -mcexec_util_thread1(ihk_os_t os, unsigned long arg, struct file *file) +long mcexec_uti_get_ctx(ihk_os_t os, struct uti_get_ctx_desc __user *udesc) { - void **__user uparam = (void ** __user)arg; - void *param[7]; - unsigned long p_rctx; + struct uti_get_ctx_desc desc; unsigned long phys; - void *__user u_rctx; - void *rctx; + struct uti_ctx *rctx; int rc = 0; - unsigned long free_address; - unsigned long free_size; unsigned long icurrent = (unsigned long)current; - if(copy_from_user(param, uparam, sizeof(void *) * 7)) { - return -EFAULT; - } - p_rctx = (unsigned long)param[0]; - u_rctx = (void *__user)param[1]; - free_address = (unsigned long)param[4]; - free_size = (unsigned long)param[5]; - - phys = ihk_device_map_memory(ihk_os_to_dev(os), p_rctx, PAGE_SIZE); -#ifdef CONFIG_MIC - rctx = ioremap_wc(phys, PAGE_SIZE); -#else - rctx = ihk_device_map_virtual(ihk_os_to_dev(os), phys, PAGE_SIZE, NULL, 0); -#endif - if(copy_to_user(u_rctx, rctx, PAGE_SIZE) || - copy_to_user((unsigned long *)(uparam + 3), &icurrent, - sizeof(unsigned long))) + if(copy_from_user(&desc, udesc, sizeof(struct uti_get_ctx_desc))) { rc = -EFAULT; + goto out; + } - ((unsigned long *)rctx)[0] = free_address; - ((unsigned long *)rctx)[1] = free_size; - ((unsigned long *)rctx)[2] = (unsigned long)param[6]; + phys = ihk_device_map_memory(ihk_os_to_dev(os), desc.rp_rctx, sizeof(struct uti_ctx)); +#ifdef CONFIG_MIC + rctx = ioremap_wc(phys, sizeof(struct uti_ctx)); +#else + rctx = ihk_device_map_virtual(ihk_os_to_dev(os), phys, sizeof(struct uti_ctx), NULL, 0); +#endif + if (copy_to_user(desc.rctx, rctx->ctx, sizeof(struct uti_ctx))) { + rc = -EFAULT; + goto unmap_and_out; + } + if (copy_to_user(&udesc->key, &icurrent, sizeof(unsigned long))) { + rc = -EFAULT; + goto unmap_and_out; + } + + rctx->uti_refill_tid = desc.uti_refill_tid; + + unmap_and_out: #ifdef CONFIG_MIC iounmap(rctx); #else - ihk_device_unmap_virtual(ihk_os_to_dev(os), rctx, PAGE_SIZE); + ihk_device_unmap_virtual(ihk_os_to_dev(os), rctx, sizeof(struct uti_ctx)); #endif - ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE); - + ihk_device_unmap_memory(ihk_os_to_dev(os), phys, sizeof(struct uti_ctx)); + out: return rc; } -long -mcexec_util_thread2(ihk_os_t os, unsigned long arg, struct file *file) +long mcexec_uti_save_fs(ihk_os_t os, struct uti_save_fs_desc __user *udesc, struct file *file) { + int rc = 0; void *usp = get_user_sp(); struct mcos_handler_info *info; struct host_thread *thread; unsigned long flags; - void **__user param = (void **__user )arg; - void *__user rctx = (void *__user)param[1]; - void *__user lctx = (void *__user)param[2]; + struct uti_save_fs_desc desc; struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct mcctrl_per_proc_data *ppd; - save_fs_ctx(lctx); + if(copy_from_user(&desc, udesc, sizeof(struct uti_save_fs_desc))) { + printk("%s: Error: copy_from_user failed\n", __FUNCTION__); + rc = -EFAULT; + goto out; + } + + save_fs_ctx(desc.lctx); info = ihk_os_get_mcos_private_data(file); thread = kmalloc(sizeof(struct host_thread), GFP_KERNEL); memset(thread, '\0', sizeof(struct host_thread)); thread->pid = task_tgid_vnr(current); thread->tid = task_pid_vnr(current); thread->usp = (unsigned long)usp; - thread->lfs = get_fs_ctx(lctx); - thread->rfs = get_fs_ctx(rctx); + thread->lfs = get_fs_ctx(desc.lctx); + thread->rfs = get_fs_ctx(desc.rctx); thread->handler = info; write_lock_irqsave(&host_thread_lock, flags); @@ -2477,7 +2480,8 @@ mcexec_util_thread2(ihk_os_t os, unsigned long arg, struct file *file) */ ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(current)); pr_ppd("get", task_pid_vnr(current), ppd); - return 0; + out: + return rc; } /* Return value: 0 if target is uti thread, -EINVAL if not */ @@ -3118,11 +3122,11 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, case MCEXEC_UP_SYS_UNSHARE: return mcexec_sys_unshare((struct sys_unshare_desc *)arg); - case MCEXEC_UP_UTIL_THREAD1: - return mcexec_util_thread1(os, arg, file); + case MCEXEC_UP_UTI_GET_CTX: + return mcexec_uti_get_ctx(os, (struct uti_get_ctx_desc *)arg); - case MCEXEC_UP_UTIL_THREAD2: - return mcexec_util_thread2(os, arg, file); + case MCEXEC_UP_UTI_SAVE_FS: + return mcexec_uti_save_fs(os, (struct uti_save_fs_desc *)arg, file); case MCEXEC_UP_SIG_THREAD: return mcexec_sig_thread(os, arg, file); diff --git a/executer/kernel/mcctrl/driver.c b/executer/kernel/mcctrl/driver.c index 17c6c71c..3f9bb37c 100644 --- a/executer/kernel/mcctrl/driver.c +++ b/executer/kernel/mcctrl/driver.c @@ -83,8 +83,8 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = { { .request = MCEXEC_UP_SYS_MOUNT, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_SYS_UMOUNT, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_SYS_UNSHARE, .func = mcctrl_ioctl }, - { .request = MCEXEC_UP_UTIL_THREAD1, .func = mcctrl_ioctl }, - { .request = MCEXEC_UP_UTIL_THREAD2, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_UTI_GET_CTX, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_UTI_SAVE_FS, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_SIG_THREAD, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_SYSCALL_THREAD, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_TERMINATE_THREAD, .func = mcctrl_ioctl }, diff --git a/executer/user/arch/x86_64/archdep.S b/executer/user/arch/x86_64/archdep.S index 89bd4021..6cc5351d 100644 --- a/executer/user/arch/x86_64/archdep.S +++ b/executer/user/arch/x86_64/archdep.S @@ -1,15 +1,22 @@ /* -arg: rdi, rsi, rdx, rcx, r8, r9 -ret: rax +Calling convention: + arg: rdi, rsi, rdx, rcx, r8, r9 + ret: rax -rax syscall number -syscall: (rax:num) rdi rsi rdx r10 r8 r9 (rcx:ret addr) -fd, cmd, param -rdi: fd -rsi: cmd -rdx: param -rcx: save area -r8: new thread context + rdi: fd + rsi: cmd + rdx: param + rcx: save area + r8: new thread context + +Syscam call convention: + syscall number: rax + arg: rdi, rsi, rdx, r10, r8, r9 + return addr: rcx + + rdi: fd + rsi: cmd + rdx: param */ .global switch_ctx @@ -91,6 +98,7 @@ switch_ctx: 1: mov $0xffffffffffffffff,%eax + retq 2: pushq %rax movq $158,%rax /* arch_prctl */ diff --git a/executer/user/archdep.h b/executer/user/archdep.h index abe81042..4a655203 100644 --- a/executer/user/archdep.h +++ b/executer/user/archdep.h @@ -1,4 +1,6 @@ -extern int switch_ctx(int fd, unsigned long cmd, void **param, void *lctx, void *rctx); +#include "../include/uprotocol.h" + +extern int switch_ctx(int fd, unsigned long cmd, struct uti_save_fs_desc *desc, void *lctx, void *rctx); extern unsigned long compare_and_swap(unsigned long *addr, unsigned long old, unsigned long new); extern unsigned int compare_and_swap_int(unsigned int *addr, unsigned int old, unsigned int new); extern int archdep_syscall(struct syscall_wait_desc *w, long *ret); diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index ad1fb93a..1bb91c26 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -2881,18 +2881,18 @@ static void kill_thread(unsigned long tid, int sig) } } -static long util_thread(struct thread_data_s *my_thread, unsigned long uctx_pa, int remote_tid, unsigned long pattr, unsigned long uti_clv, unsigned long _uti_desc) +static long util_thread(struct thread_data_s *my_thread, unsigned long rp_rctx, int remote_tid, unsigned long pattr, unsigned long uti_clv, unsigned long _uti_desc) { - int i; - void *lctx; - void *rctx; - void *param[7]; + struct uti_get_ctx_desc get_ctx_desc; + struct uti_save_fs_desc save_fs_desc; int rc = 0; - void *uti_wp = (void*)-1; + + struct thread_data_s *tp; pthread_barrier_init(&uti_init_ready, NULL, 2); if ((rc = create_worker_thread(&tp, &uti_init_ready))) { printf("%s: Error: create_worker_thread failed (%d)\n", __FUNCTION__, rc); + rc = -EINVAL; goto out; } pthread_barrier_wait(&uti_init_ready); @@ -2900,18 +2900,12 @@ static long util_thread(struct thread_data_s *my_thread, unsigned long uctx_pa, uti_desc = (struct uti_desc *)_uti_desc; if (!uti_desc) { - fprintf(stderr, "%s: ERROR: uti_desc isn't set. Use mcexec.sh instead of mcexec\n", __FUNCTION__); - exit(1); + printf("%s: ERROR: uti_desc isn't set. Use mcexec.sh instead of mcexec\n", __FUNCTION__); + rc = -EINVAL; + goto out; } /* Initialize uti related variables for syscall_intercept */ - - uti_wp = mmap(NULL, PAGE_SIZE * 3, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, -1, 0); - if (uti_wp == (void *)-1) { - exit(1); - } - uti_desc->fd = fd; rc = syscall(888); @@ -2919,42 +2913,21 @@ static long util_thread(struct thread_data_s *my_thread, unsigned long uctx_pa, fprintf(stderr, "%s: WARNING: syscall_intercept returned %x\n", __FUNCTION__, rc); } - /* Get the context of the thread migrating to Linux */ -#ifdef POSTK_DEBUG_ARCH_DEP_35 - lctx = (char *)uti_wp + page_size; - rctx = (char *)lctx + page_size; -#else - lctx = (char *)uti_wp + PAGE_SIZE; - rctx = (char *)lctx + PAGE_SIZE; -#endif /* POSTK_DEBUG_ARCH_DEP_35 */ + /* Get the remote context, record refill tid */ + get_ctx_desc.rp_rctx = rp_rctx; + get_ctx_desc.rctx = uti_desc->rctx; + get_ctx_desc.lctx = uti_desc->lctx; + get_ctx_desc.uti_refill_tid = tp->tid; - param[0] = (void *)uctx_pa; /* Source address, kernel space */ - param[1] = rctx; /* Destination address, user space */ - param[2] = lctx; - param[4] = uti_desc->wp; -#ifdef POSTK_DEBUG_ARCH_DEP_35 - param[5] = (void *)(page_size * 3); -#else /* POSTK_DEBUG_ARCH_DEP_35 */ - param[5] = (void *)(PAGE_SIZE * 3); -#endif /* POSTK_DEBUG_ARCH_DEP_35 */ - param[6] = (void *)tp->tid; - printf("%s: param[6]=%ld,tid=%ld\n", __FUNCTION__, (long)param[6], (long)((void *)tp->tid)); - - __dprintf("%s: before MCEXEC_UP_UTIL_THREAD1\n", __FUNCTION__); - - /* 1. Copy context from kernel space to user space - 2. Write uti_wp addr, its size for McKernel to uctx_pa - Note that this overwrites context */ - if ((rc = ioctl(fd, MCEXEC_UP_UTIL_THREAD1, param)) == -1) { - fprintf(stderr, "util_thread1: %d errno=%d\n", rc, errno); + if ((rc = ioctl(fd, MCEXEC_UP_UTI_GET_CTX, &get_ctx_desc))) { + fprintf(stderr, "%s: Error: MCEXEC_UP_UTI_GET_CTX failed (%d)\n", __FUNCTION__, errno); rc = -errno; goto out; } - /* Record the info of the thread migrating to Linux */ - uti_desc->wp = uti_wp; + /* Initialize uti thread info */ uti_desc->mck_tid = remote_tid; - uti_desc->key = (unsigned long)param[3]; /* key to find thread, i.e. struct task_struct * */ + uti_desc->key = get_ctx_desc.key; uti_desc->pid = getpid(); uti_desc->tid = gettid(); uti_desc->uti_clv = uti_clv; @@ -2965,12 +2938,6 @@ static long util_thread(struct thread_data_s *my_thread, unsigned long uctx_pa, rc = -ENOMEM; goto out; } - for (i = 1; i <= 10; i++) { - uti_desc->syscall_param = (struct syscall_struct *)uti_desc->wp + i; - *(void **)uti_desc->syscall_param = uti_desc->syscall_param_top; - uti_desc->syscall_param_top = uti_desc->syscall_param; - } - memset(uti_desc->wp, '\0', sizeof(long)); if (pattr) { struct uti_attr_desc desc; @@ -2979,30 +2946,22 @@ static long util_thread(struct thread_data_s *my_thread, unsigned long uctx_pa, ioctl(fd, MCEXEC_UP_UTI_ATTR, &desc); } - /* McKernel would create the thread detached, so detach myself */ - if ((rc = pthread_detach(my_thread->thread_id)) < 0) { - fprintf(stderr, "%s: ERROR pthread_detach returned %d\n", __FUNCTION__, rc); - goto out; - } - my_thread->detached = 1; - /* Start intercepting syscalls. Note that it dereferences pointers in uti_desc. */ uti_desc->start_syscall_intercept = 1; - if ((rc = switch_ctx(fd, MCEXEC_UP_UTIL_THREAD2, param, lctx, rctx)) + /* Save remote and local FS and then contex-switch */ + save_fs_desc.rctx = uti_desc->rctx; + save_fs_desc.lctx = uti_desc->lctx; + + if ((rc = switch_ctx(fd, MCEXEC_UP_UTI_SAVE_FS, &save_fs_desc, uti_desc->lctx, uti_desc->rctx)) < 0) { - fprintf(stderr, "%s: ERROR switch_ctx returned %d\n", __FUNCTION__, rc); + fprintf(stderr, "%s: ERROR switch_ctx failed (%d)\n", __FUNCTION__, rc); + goto out; } - fprintf(stderr, "return from util_thread2 rc=%d\n", rc); - pthread_exit(NULL); + fprintf(stderr, "%s: ERROR: Returned from switch_ctx (%d)\n", __FUNCTION__, rc); + rc = -EINVAL; out: - if (uti_desc != (void*)-1 && uti_desc->wp != (void*)-1) -#ifdef POSTK_DEBUG_ARCH_DEP_35 - munmap(uti_desc->wp, page_size * 3); -#else /* POSTK_DEBUG_ARCH_DEP_35 */ - munmap(uti_desc->wp, PAGE_SIZE * 3); -#endif /* POSTK_DEBUG_ARCH_DEP_35 */ return rc; } @@ -4078,10 +4037,8 @@ return_execve2: w.sr.args[2], w.sr.args[3], w.sr.args[4]); } else { - ret = munmap((void *)w.sr.args[1], - w.sr.args[2]); - if (ret == -1) - ret = -errno; + __eprintf("__NR_sched_setaffinity: invalid argument (%lx)\n", w.sr.args[0]); + ret = -EINVAL; } do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); break; diff --git a/executer/user/syscall_intercept.c b/executer/user/syscall_intercept.c index de8efad5..132cb9ba 100644 --- a/executer/user/syscall_intercept.c +++ b/executer/user/syscall_intercept.c @@ -24,6 +24,7 @@ hook(long syscall_number, int tid = uti_syscall0(__NR_gettid); struct terminate_thread_desc term_desc; unsigned long code; + int stack_top; if (!uti_desc.start_syscall_intercept) { return 1; /* System call isn't taken over */ @@ -50,34 +51,40 @@ hook(long syscall_number, case __NR_munmap: case __NR_mprotect: case __NR_mremap: - if (!uti_desc.syscall_param_top) { + /* Overflow check */ + if (uti_desc.syscall_stack_top == -1) { *result = -ENOMEM; return 0; } - else { - /* Pop syscall_struct list for reentrant safety */ - uti_desc.syscall_param = uti_desc.syscall_param_top; - uti_desc.syscall_param_top = *(void **)uti_desc.syscall_param; - - uti_desc.syscall_param->number = syscall_number; - uti_desc.syscall_param->args[0] = arg0; - uti_desc.syscall_param->args[1] = arg1; - uti_desc.syscall_param->args[2] = arg2; - uti_desc.syscall_param->args[3] = arg3; - uti_desc.syscall_param->args[4] = arg4; - uti_desc.syscall_param->args[5] = arg5; - uti_desc.syscall_param->uti_clv = uti_desc.uti_clv; - uti_desc.syscall_param->ret = -EINVAL; - uti_syscall3(__NR_ioctl, uti_desc.fd, MCEXEC_UP_SYSCALL_THREAD, (long)uti_desc.syscall_param); - *result = uti_desc.syscall_param->ret; - - /* push syscall_struct list */ - *(void **)uti_desc.syscall_param = uti_desc.syscall_param_top; - uti_desc.syscall_param_top = uti_desc.syscall_param; - - return 0; /* System call is taken over */ + + /* Sanity check */ + if (uti_desc.syscall_stack_top < 0 || uti_desc.syscall_stack_top >= UTI_SZ_SYSCALL_STACK) { + *result = -EINVAL; + return 0; } - break; + + /* Store the return value in the stack to prevent it from getting corrupted + when an interrupt happens just after ioctl() and before copying the return + value to *result */ + stack_top = __sync_fetch_and_sub(&uti_desc.syscall_stack_top, 1); + + uti_desc.syscall_stack[stack_top].number = syscall_number; + uti_desc.syscall_stack[stack_top].args[0] = arg0; + uti_desc.syscall_stack[stack_top].args[1] = arg1; + uti_desc.syscall_stack[stack_top].args[2] = arg2; + uti_desc.syscall_stack[stack_top].args[3] = arg3; + uti_desc.syscall_stack[stack_top].args[4] = arg4; + uti_desc.syscall_stack[stack_top].args[5] = arg5; + uti_desc.syscall_stack[stack_top].uti_clv = uti_desc.uti_clv; + uti_desc.syscall_stack[stack_top].ret = -EINVAL; + + uti_syscall3(__NR_ioctl, uti_desc.fd, MCEXEC_UP_SYSCALL_THREAD, (long)(uti_desc.syscall_stack + stack_top)); + *result = uti_desc.syscall_stack[stack_top].ret; + + /* push syscall_struct list */ + __sync_fetch_and_add(&uti_desc.syscall_stack_top, 1); + + return 0; /* System call is taken over */ case __NR_exit_group: code = 0x100000000; goto make_remote_thread_exit; @@ -116,9 +123,13 @@ hook(long syscall_number, static __attribute__((constructor)) void init(void) { - // Set up the callback function + /* Set up the callback function */ intercept_hook_point = hook; - + + /* Initialize uti_desc */ + uti_desc.syscall_stack_top = UTI_SZ_SYSCALL_STACK - 1; + + /* Pass address of uti_desc to McKernel */ uti_syscall1(733, (unsigned long)&uti_desc); } diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index f41430e4..5b13dc73 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -590,6 +590,15 @@ typedef struct uti_attr { uint64_t flags; /* Representing location and behavior hints by bitmap */ } uti_attr_t; +struct uti_ctx { + union { + char ctx[4096]; + struct { + int uti_refill_tid; + }; + }; +}; + struct move_pages_smp_req { unsigned long count; const void **user_virt_addr; diff --git a/kernel/process.c b/kernel/process.c index 0ca55c0c..83829e62 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -2632,7 +2632,7 @@ void __find_and_replace_tid(struct process *proc, struct thread *thread, int new proc->tids[i].thread = NULL; proc->tids[i].tid = new_tid; - kprintf("%s: tid %d (thread %p) has been relaced with tid %d\n", + dkprintf("%s: tid %d (thread %p) has been relaced with tid %d\n", __FUNCTION__, thread->tid, thread, new_tid); break; } diff --git a/kernel/syscall.c b/kernel/syscall.c index 72e7fcc5..f54faa2a 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -9114,14 +9114,12 @@ int util_show_syscall_profile() int util_thread(struct uti_attr *arg) { - volatile unsigned long *context; - unsigned long pcontext; - struct cpu_local_var *uti_clv; + struct uti_ctx *rctx = NULL; + unsigned long rp_rctx; + struct cpu_local_var *uti_clv = NULL; struct syscall_request request IHK_DMA_ALIGN; long rc; struct thread *thread = cpu_local_var(current); - unsigned long free_address; - unsigned long free_size; struct kuti_attr { long parent_cpuid; struct uti_attr attr; @@ -9129,25 +9127,25 @@ int util_thread(struct uti_attr *arg) thread->uti_state = UTI_STATE_PROLOGUE; - context = (volatile unsigned long *)ihk_mc_alloc_pages(1, - IHK_MC_AP_NOWAIT); - if (!context) { - return -ENOMEM; + rctx = kmalloc(sizeof(struct uti_ctx), IHK_MC_AP_NOWAIT); + if (!rctx) { + rc = -ENOMEM; + goto out; } - pcontext = virt_to_phys((void *)context); - save_uctx((void *)context, NULL); + rp_rctx = virt_to_phys((void *)rctx); + save_uctx((void *)rctx->ctx, NULL); /* Create a copy of clv and replace clv with it when the Linux thread calls in a McKernel function */ uti_clv = kmalloc(sizeof(struct cpu_local_var), IHK_MC_AP_NOWAIT); if (!uti_clv) { - ihk_mc_free_pages((void *)context, 1); - return -ENOMEM; + rc = -ENOMEM; + goto out; } memcpy(uti_clv, get_this_cpu_local_var(), sizeof(struct cpu_local_var)); request.number = __NR_sched_setaffinity; request.args[0] = 0; - request.args[1] = pcontext; + request.args[1] = rp_rctx; request.args[2] = 0; if (arg) { memcpy(&kattr.attr, arg, sizeof(struct uti_attr)); @@ -9164,14 +9162,15 @@ int util_thread(struct uti_attr *arg) util_show_syscall_profile(); - /* These are written by mcexec_util_thread1() */ - free_address = context[0]; - free_size = context[1]; - thread->uti_refill_tid = context[2]; - dkprintf("%s: mcexec worker tid=%d\n", __FUNCTION__, context[2]); + /* Save it before freed */ + thread->uti_refill_tid = rctx->uti_refill_tid; + dkprintf("%s: mcexec worker tid=%d\n", __FUNCTION__, thread->uti_refill_tid); - ihk_mc_free_pages((void *)context, 1); + kfree(rctx); + rctx = NULL; + kfree(uti_clv); + uti_clv = NULL; if (rc >= 0) { if (rc & 0x100000000) { /* exit_group */ @@ -9181,11 +9180,6 @@ int util_thread(struct uti_attr *arg) } else { /* exit or killed-by-signal detected */ dkprintf("%s: exit or killed by signal, pid=%d,tid=%d,rc=%lx\n", __FUNCTION__, thread->proc->pid, thread->tid, rc); - request.number = __NR_sched_setaffinity; - request.args[0] = 1; - request.args[1] = free_address; - request.args[2] = free_size; - do_syscall(&request, ihk_mc_get_processor_id(), 0); do_exit(rc); } } else if (rc == -ERESTARTSYS) { @@ -9194,8 +9188,17 @@ int util_thread(struct uti_attr *arg) thread->proc->nohost = 1; do_exit(rc); } else { - kprintf("%s: unknown error (%ld)\n", __FUNCTION__, rc); + kprintf("%s: ERROR: do_syscall() failed (%ld)\n", __FUNCTION__, rc); } + + out: + if (rctx) { + kfree(rctx); + } + if (uti_clv) { + kfree(uti_clv); + } + return rc; }