From c32edff2bbd9ab55500de0e4f165f977300c0de3 Mon Sep 17 00:00:00 2001 From: "Shiratori, Takehiro" Date: Tue, 12 Mar 2019 14:35:27 +0900 Subject: [PATCH] uti: rename x86-specific 'fs' to 'tls' + arm implem Note: the original fujitsu implementation didn't rename the various save_fs function/desc to save_tls for some reason, might as well go all the way though... Change-Id: Ic362c15c8b320c4d258d2ead8c5fd4eafd9d0ae9 Fujitsu: POSTK_DEBUG_ARCH_DEP_91 --- executer/include/uprotocol.h | 2 +- executer/kernel/mcctrl/arch/arm64/archdeps.c | 45 ++++++++++++++----- executer/kernel/mcctrl/arch/x86_64/archdeps.c | 30 ++++++++----- executer/kernel/mcctrl/control.c | 26 +++++------ executer/kernel/mcctrl/mcctrl.h | 8 ++-- executer/user/arch/x86_64/archdep.S | 2 +- executer/user/archdep.h | 4 +- executer/user/mcexec.c | 8 ++-- 8 files changed, 79 insertions(+), 46 deletions(-) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index dc2c037c..664128d0 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -358,7 +358,7 @@ struct uti_get_ctx_desc { unsigned long key; /* OUT: struct task_struct* of mcexec thread, used to search struct host_thread */ }; -struct uti_save_fs_desc { +struct uti_switch_ctx_desc { void *rctx; /* Remote context */ void *lctx; /* Local context */ }; diff --git a/executer/kernel/mcctrl/arch/arm64/archdeps.c b/executer/kernel/mcctrl/arch/arm64/archdeps.c index 63189245..7bfd69e1 100644 --- a/executer/kernel/mcctrl/arch/arm64/archdeps.c +++ b/executer/kernel/mcctrl/arch/arm64/archdeps.c @@ -145,14 +145,13 @@ out: void * get_user_sp(void) { - /* TODO; skeleton for UTI */ - return NULL; + return (void *)current_pt_regs()->sp; } void set_user_sp(void *usp) { - /* TODO; skeleton for UTI */ + current_pt_regs()->sp = (unsigned long)usp; } struct trans_uctx { @@ -163,22 +162,44 @@ struct trans_uctx { }; void -restore_fs(unsigned long fs) +restore_tls(unsigned long addr) { - /* TODO; skeleton for UTI */ + const unsigned long tpidrro = 0; + + asm volatile( + " msr tpidr_el0, %0\n" + " msr tpidrro_el0, %1" + : : "r" (addr), "r" (tpidrro)); } void -save_fs_ctx(void *ctx) +save_tls_ctx(void __user *ctx) { - /* TODO; skeleton for UTI */ + struct trans_uctx __user *tctx = ctx; + unsigned long baseaddr; + + asm volatile( + " mrs %0, tpidr_el0" + : "=r" (baseaddr)); + + if (copy_to_user(&tctx->tls_baseaddr, &baseaddr, + sizeof(tctx->tls_baseaddr))) { + pr_err("%s: copy_to_user failed.\n", __func__); + return; + } } unsigned long -get_fs_ctx(void *ctx) +get_tls_ctx(void __user *ctx) { - /* TODO; skeleton for UTI */ - return 0; + struct trans_uctx __user *tctx = ctx; + struct trans_uctx kctx; + + if (copy_from_user(&kctx, tctx, sizeof(struct trans_uctx))) { + pr_err("%s: copy_from_user failed.\n", __func__); + return 0; + } + return kctx.tls_baseaddr; } #if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) @@ -294,7 +315,7 @@ out: * Context register save/load is done on Linux (get from current_pt_regs). * Do TLS save/load and register host_thread with ioctl. */ -long arch_switch_ctx(struct uti_save_fs_desc *desc) +long arch_switch_ctx(struct uti_switch_ctx_desc *desc) { int rc = 0; struct trans_uctx *__user rctx = NULL; @@ -318,7 +339,7 @@ long arch_switch_ctx(struct uti_save_fs_desc *desc) rc = -EFAULT; goto out; } - restore_fs(get_fs_ctx(rctx)); + restore_tls(get_tls_ctx(rctx)); out: return rc; diff --git a/executer/kernel/mcctrl/arch/x86_64/archdeps.c b/executer/kernel/mcctrl/arch/x86_64/archdeps.c index 06c60479..e0bac0e0 100644 --- a/executer/kernel/mcctrl/arch/x86_64/archdeps.c +++ b/executer/kernel/mcctrl/arch/x86_64/archdeps.c @@ -261,25 +261,35 @@ struct trans_uctx { }; void -restore_fs(unsigned long fs) +restore_tls(unsigned long addr) { - wrmsrl(MSR_FS_BASE, fs); + wrmsrl(MSR_FS_BASE, addr); } void -save_fs_ctx(void *ctx) +save_tls_ctx(void __user *ctx) { - struct trans_uctx *tctx = ctx; + struct trans_uctx __user *tctx = ctx; + struct trans_uctx kctx; - rdmsrl(MSR_FS_BASE, tctx->fs); + if (copy_from_user(&kctx, tctx, sizeof(struct trans_uctx))) { + pr_err("%s: copy_from_user failed.\n", __func__); + return; + } + rdmsrl(MSR_FS_BASE, kctx.fs); } unsigned long -get_fs_ctx(void *ctx) +get_tls_ctx(void __user *ctx) { - struct trans_uctx *tctx = ctx; + struct trans_uctx __user *tctx = ctx; + struct trans_uctx kctx; - return tctx->fs; + if (copy_from_user(&kctx, tctx, sizeof(struct trans_uctx))) { + pr_err("%s: copy_from_user failed.\n", __func__); + return 0; + } + return kctx.fs; } unsigned long @@ -370,9 +380,9 @@ static inline bool pte_is_write_combined(pte_t pte) /* * The assembler switch_ctx is save/load registers in the context. - * Do FS save/load and register host_thread with ioctl. + * Do TLS save/load and register host_thread with ioctl. */ -long arch_switch_ctx(struct uti_save_fs_desc *desc) +long arch_switch_ctx(struct uti_switch_ctx_desc *desc) { return 0; } diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index d1539671..3d9b4d97 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -2434,10 +2434,10 @@ long mcctrl_getrusage(ihk_os_t ihk_os, struct mcctrl_ioctl_getrusage_desc *__use extern void *get_user_sp(void); 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 *); +extern void restore_tls(unsigned long addr); +extern void save_tls_ctx(void __user *ctx); +extern unsigned long get_tls_ctx(void __user *ctx); +extern unsigned long get_rsp_ctx(void *ctx); long mcexec_uti_get_ctx(ihk_os_t os, struct uti_get_ctx_desc __user *udesc) { @@ -2481,7 +2481,7 @@ long mcexec_uti_get_ctx(ihk_os_t os, struct uti_get_ctx_desc __user *udesc) return rc; } -long mcctrl_switch_ctx(ihk_os_t os, struct uti_save_fs_desc __user *udesc, +long mcctrl_switch_ctx(ihk_os_t os, struct uti_switch_ctx_desc __user *udesc, struct file *file) { int rc = 0; @@ -2489,7 +2489,7 @@ long mcctrl_switch_ctx(ihk_os_t os, struct uti_save_fs_desc __user *udesc, struct mcos_handler_info *info; struct host_thread *thread; unsigned long flags; - struct uti_save_fs_desc desc; + struct uti_switch_ctx_desc desc; struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct mcctrl_per_proc_data *ppd; @@ -2499,7 +2499,7 @@ long mcctrl_switch_ctx(ihk_os_t os, struct uti_save_fs_desc __user *udesc, goto out; } - if (copy_from_user(&desc, udesc, sizeof(struct uti_save_fs_desc))) { + if (copy_from_user(&desc, udesc, sizeof(struct uti_switch_ctx_desc))) { printk("%s: Error: copy_from_user failed\n", __FUNCTION__); rc = -EFAULT; goto out; @@ -2510,15 +2510,15 @@ long mcctrl_switch_ctx(ihk_os_t os, struct uti_save_fs_desc __user *udesc, goto out; } - save_fs_ctx(desc.lctx); + save_tls_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(desc.lctx); - thread->rfs = get_fs_ctx(desc.rctx); + thread->ltls = get_tls_ctx(desc.lctx); + thread->rtls = get_tls_ctx(desc.rctx); thread->handler = info; write_lock_irqsave(&host_thread_lock, flags); @@ -2564,9 +2564,9 @@ mcexec_sig_thread(ihk_os_t os, unsigned long arg, struct file *file) read_unlock_irqrestore(&host_thread_lock, flags); if (thread) { if (arg) - restore_fs(thread->lfs); + restore_tls(thread->ltls); else - restore_fs(thread->rfs); + restore_tls(thread->rtls); goto out; } ret = -EINVAL; @@ -3268,7 +3268,7 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, return mcexec_uti_get_ctx(os, (struct uti_get_ctx_desc *)arg); case MCEXEC_UP_UTI_SWITCH_CTX: - return mcctrl_switch_ctx(os, (struct uti_save_fs_desc *)arg, + return mcctrl_switch_ctx(os, (struct uti_switch_ctx_desc *)arg, file); case MCEXEC_UP_SIG_THREAD: diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index eca0604c..c4a8254a 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -565,9 +565,9 @@ struct mcctrl_ioctl_getrusage_desc { }; /* uti */ -long mcctrl_switch_ctx(ihk_os_t os, struct uti_save_fs_desc __user *desc, +long mcctrl_switch_ctx(ihk_os_t os, struct uti_switch_ctx_desc __user *desc, struct file *file); -long arch_switch_ctx(struct uti_save_fs_desc *desc); +long arch_switch_ctx(struct uti_switch_ctx_desc *desc); struct host_thread { struct list_head list; @@ -575,8 +575,8 @@ struct host_thread { int pid; int tid; unsigned long usp; - unsigned long lfs; - unsigned long rfs; + unsigned long ltls; + unsigned long rtls; }; /* Used to wake-up a Linux thread futex_wait()-ing */ diff --git a/executer/user/arch/x86_64/archdep.S b/executer/user/arch/x86_64/archdep.S index 5a26cd81..a718ae99 100644 --- a/executer/user/arch/x86_64/archdep.S +++ b/executer/user/arch/x86_64/archdep.S @@ -18,7 +18,7 @@ Syscam call convention: rsi: cmd rdx: param - Save and switch the context including FS. + Save and switch the context including TLS. */ .global switch_ctx diff --git a/executer/user/archdep.h b/executer/user/archdep.h index 4a655203..cf5614ee 100644 --- a/executer/user/archdep.h +++ b/executer/user/archdep.h @@ -1,6 +1,8 @@ #include "../include/uprotocol.h" -extern int switch_ctx(int fd, unsigned long cmd, struct uti_save_fs_desc *desc, void *lctx, void *rctx); +extern int switch_ctx(int fd, unsigned long cmd, + struct uti_switch_ctx_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 97d5aba8..c590981c 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -2814,7 +2814,7 @@ static void kill_thread(unsigned long tid, int sig, 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) { struct uti_get_ctx_desc get_ctx_desc; - struct uti_save_fs_desc save_fs_desc; + struct uti_switch_ctx_desc switch_ctx_desc; int rc = 0; struct thread_data_s *tp; @@ -2891,10 +2891,10 @@ static long util_thread(struct thread_data_s *my_thread, unsigned long rp_rctx, uti_desc->start_syscall_intercept = 1; /* Save remote and local FS and then contex-switch */ - save_fs_desc.rctx = uti_desc->rctx; - save_fs_desc.lctx = uti_desc->lctx; + switch_ctx_desc.rctx = uti_desc->rctx; + switch_ctx_desc.lctx = uti_desc->lctx; - if ((rc = switch_ctx(fd, MCEXEC_UP_UTI_SWITCH_CTX, &save_fs_desc, + if ((rc = switch_ctx(fd, MCEXEC_UP_UTI_SWITCH_CTX, &switch_ctx_desc, uti_desc->lctx, uti_desc->rctx)) < 0) { fprintf(stderr, "%s: ERROR switch_ctx failed (%d)\n", __FUNCTION__, rc);