diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index dedfc373..dc2c037c 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -55,7 +55,7 @@ #define MCEXEC_UP_SYS_UNSHARE 0x30a02916 #define MCEXEC_UP_UTI_GET_CTX 0x30a02920 -#define MCEXEC_UP_UTI_SAVE_FS 0x30a02921 +#define MCEXEC_UP_UTI_SWITCH_CTX 0x30a02921 #define MCEXEC_UP_SIG_THREAD 0x30a02922 #define MCEXEC_UP_SYSCALL_THREAD 0x30a02924 #define MCEXEC_UP_TERMINATE_THREAD 0x30a02925 diff --git a/executer/kernel/mcctrl/arch/arm64/archdeps.c b/executer/kernel/mcctrl/arch/arm64/archdeps.c index 09a7c488..63189245 100644 --- a/executer/kernel/mcctrl/arch/arm64/archdeps.c +++ b/executer/kernel/mcctrl/arch/arm64/archdeps.c @@ -1,7 +1,12 @@ -/* archdeps.c COPYRIGHT FUJITSU LIMITED 2016 */ +/* archdeps.c COPYRIGHT FUJITSU LIMITED 2016-2019 */ #include #include #include +#if KERNEL_VERSION(4, 11, 0) <= LINUX_VERSION_CODE +#include +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */ +#include +#include #include #include "config.h" #include "../../mcctrl.h" @@ -150,30 +155,11 @@ set_user_sp(void *usp) /* TODO; skeleton for UTI */ } -/* TODO; skeleton for UTI */ struct trans_uctx { volatile int cond; int fregsize; - - unsigned long rax; - unsigned long rbx; - unsigned long rcx; - unsigned long rdx; - unsigned long rsi; - unsigned long rdi; - unsigned long rbp; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long r11; - unsigned long r12; - unsigned long r13; - unsigned long r14; - unsigned long r15; - unsigned long rflags; - unsigned long rip; - unsigned long rsp; - unsigned long fs; + struct user_pt_regs regs; + unsigned long tls_baseaddr; }; void @@ -302,3 +288,38 @@ out: error, rva, rpa, pgsize); return error; } + +/* + * Assembler switch_ctx executes only ioctl. + * 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) +{ + int rc = 0; + struct trans_uctx *__user rctx = NULL; + struct trans_uctx *__user lctx = NULL; + struct trans_uctx klctx = { + .regs = current_pt_regs()->user_regs, + }; + + rctx = desc->rctx; + lctx = desc->lctx; + + if (copy_to_user(lctx, &klctx, sizeof(klctx))) { + pr_err("%s: Error: copy_to_user failed\n", __func__); + rc = -EFAULT; + goto out; + } + + if (copy_from_user(¤t_pt_regs()->user_regs, + &rctx->regs, sizeof(rctx->regs))) { + pr_err("%s: Error: copy_from_user failed\n", __func__); + rc = -EFAULT; + goto out; + } + restore_fs(get_fs_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 88bbe312..06c60479 100644 --- a/executer/kernel/mcctrl/arch/x86_64/archdeps.c +++ b/executer/kernel/mcctrl/arch/x86_64/archdeps.c @@ -368,3 +368,11 @@ static inline bool pte_is_write_combined(pte_t pte) } #endif /* POSTK_DEBUG_ARCH_DEP_12 */ +/* + * The assembler switch_ctx is save/load registers in the context. + * Do FS save/load and register host_thread with ioctl. + */ +long arch_switch_ctx(struct uti_save_fs_desc *desc) +{ + return 0; +} diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 29cfa07e..d1539671 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -319,17 +319,6 @@ struct mcos_handler_info; static LIST_HEAD(host_threads); /* Used for FS switch */ DEFINE_RWLOCK(host_thread_lock); -/* Info of Linux counterpart of migrated-to-Linux thread */ -struct host_thread { - struct list_head list; - struct mcos_handler_info *handler; - int pid; - int tid; - unsigned long usp; - unsigned long lfs; - unsigned long rfs; -}; - struct mcos_handler_info *new_mcos_handler_info(ihk_os_t os, struct file *file) { struct mcos_handler_info *info; @@ -2492,7 +2481,8 @@ long mcexec_uti_get_ctx(ihk_os_t os, struct uti_get_ctx_desc __user *udesc) return rc; } -long mcexec_uti_save_fs(ihk_os_t os, struct uti_save_fs_desc __user *udesc, struct file *file) +long mcctrl_switch_ctx(ihk_os_t os, struct uti_save_fs_desc __user *udesc, + struct file *file) { int rc = 0; void *usp = get_user_sp(); @@ -2509,12 +2499,17 @@ long mcexec_uti_save_fs(ihk_os_t os, struct uti_save_fs_desc __user *udesc, stru goto out; } - if(copy_from_user(&desc, udesc, sizeof(struct uti_save_fs_desc))) { + 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; } + rc = arch_switch_ctx(&desc); + if (rc < 0) { + goto out; + } + save_fs_ctx(desc.lctx); info = ihk_os_get_mcos_private_data(file); thread = kmalloc(sizeof(struct host_thread), GFP_KERNEL); @@ -3272,8 +3267,9 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, case MCEXEC_UP_UTI_GET_CTX: return mcexec_uti_get_ctx(os, (struct uti_get_ctx_desc *)arg); - case MCEXEC_UP_UTI_SAVE_FS: - return mcexec_uti_save_fs(os, (struct uti_save_fs_desc *)arg, file); + case MCEXEC_UP_UTI_SWITCH_CTX: + return mcctrl_switch_ctx(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 d521074a..30588b30 100644 --- a/executer/kernel/mcctrl/driver.c +++ b/executer/kernel/mcctrl/driver.c @@ -86,7 +86,7 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = { { .request = MCEXEC_UP_SYS_UNSHARE, .func = mcctrl_ioctl }, #endif // MCEXEC_BIND_MOUNT { .request = MCEXEC_UP_UTI_GET_CTX, .func = mcctrl_ioctl }, - { .request = MCEXEC_UP_UTI_SAVE_FS, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_UTI_SWITCH_CTX, .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/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index ac2c0dcb..eca0604c 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -124,12 +124,6 @@ enum mcctrl_os_cpu_operation { MCCTRL_OS_CPU_MAX_OP }; -/* Used to wake-up a Linux thread futex_wait()-ing */ -struct uti_futex_resp { - int done; - wait_queue_head_t wq; -}; - struct ikc_scd_packet { struct ihk_ikc_packet_header header; int msg; @@ -570,4 +564,24 @@ struct mcctrl_ioctl_getrusage_desc { size_t size_rusage; }; +/* uti */ +long mcctrl_switch_ctx(ihk_os_t os, struct uti_save_fs_desc __user *desc, + struct file *file); +long arch_switch_ctx(struct uti_save_fs_desc *desc); + +struct host_thread { + struct list_head list; + struct mcos_handler_info *handler; + int pid; + int tid; + unsigned long usp; + unsigned long lfs; + unsigned long rfs; +}; + +/* Used to wake-up a Linux thread futex_wait()-ing */ +struct uti_futex_resp { + int done; + wait_queue_head_t wq; +}; #endif diff --git a/executer/user/arch/arm64/archdep.S b/executer/user/arch/arm64/archdep.S index 57f19660..5e88dc1a 100644 --- a/executer/user/arch/arm64/archdep.S +++ b/executer/user/arch/arm64/archdep.S @@ -1,4 +1,4 @@ -/* archdep.S COPYRIGHT FUJITSU LIMITED 2017-2018 */ +/* archdep.S COPYRIGHT FUJITSU LIMITED 2017-2019 */ #include @@ -11,6 +11,8 @@ * x2 : void **param * x3 : void *lctx * x4 : void *rctx + * + * Save and switch the context including TLS. */ .global switch_ctx switch_ctx: diff --git a/executer/user/arch/x86_64/archdep.S b/executer/user/arch/x86_64/archdep.S index 6cc5351d..5a26cd81 100644 --- a/executer/user/arch/x86_64/archdep.S +++ b/executer/user/arch/x86_64/archdep.S @@ -17,6 +17,8 @@ Syscam call convention: rdi: fd rsi: cmd rdx: param + + Save and switch the context including FS. */ .global switch_ctx diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index b893c672..97d5aba8 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -2894,7 +2894,8 @@ static long util_thread(struct thread_data_s *my_thread, unsigned long rp_rctx, 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)) + if ((rc = switch_ctx(fd, MCEXEC_UP_UTI_SWITCH_CTX, &save_fs_desc, + uti_desc->lctx, uti_desc->rctx)) < 0) { fprintf(stderr, "%s: ERROR switch_ctx failed (%d)\n", __FUNCTION__, rc); goto out;