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
This commit is contained in:
committed by
Masamichi Takagi
parent
8356ef6c96
commit
c32edff2bb
@@ -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 */
|
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 *rctx; /* Remote context */
|
||||||
void *lctx; /* Local context */
|
void *lctx; /* Local context */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -145,14 +145,13 @@ out:
|
|||||||
void *
|
void *
|
||||||
get_user_sp(void)
|
get_user_sp(void)
|
||||||
{
|
{
|
||||||
/* TODO; skeleton for UTI */
|
return (void *)current_pt_regs()->sp;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_user_sp(void *usp)
|
set_user_sp(void *usp)
|
||||||
{
|
{
|
||||||
/* TODO; skeleton for UTI */
|
current_pt_regs()->sp = (unsigned long)usp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct trans_uctx {
|
struct trans_uctx {
|
||||||
@@ -163,22 +162,44 @@ struct trans_uctx {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
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
|
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
|
unsigned long
|
||||||
get_fs_ctx(void *ctx)
|
get_tls_ctx(void __user *ctx)
|
||||||
{
|
{
|
||||||
/* TODO; skeleton for UTI */
|
struct trans_uctx __user *tctx = ctx;
|
||||||
return 0;
|
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)
|
#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).
|
* Context register save/load is done on Linux (get from current_pt_regs).
|
||||||
* Do TLS 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)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct trans_uctx *__user rctx = NULL;
|
struct trans_uctx *__user rctx = NULL;
|
||||||
@@ -318,7 +339,7 @@ long arch_switch_ctx(struct uti_save_fs_desc *desc)
|
|||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
restore_fs(get_fs_ctx(rctx));
|
restore_tls(get_tls_ctx(rctx));
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -261,25 +261,35 @@ struct trans_uctx {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
restore_fs(unsigned long fs)
|
restore_tls(unsigned long addr)
|
||||||
{
|
{
|
||||||
wrmsrl(MSR_FS_BASE, fs);
|
wrmsrl(MSR_FS_BASE, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
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
|
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.
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 *get_user_sp(void);
|
||||||
extern void set_user_sp(unsigned long);
|
extern void set_user_sp(unsigned long);
|
||||||
extern void restore_fs(unsigned long fs);
|
extern void restore_tls(unsigned long addr);
|
||||||
extern void save_fs_ctx(void *);
|
extern void save_tls_ctx(void __user *ctx);
|
||||||
extern unsigned long get_fs_ctx(void *);
|
extern unsigned long get_tls_ctx(void __user *ctx);
|
||||||
extern unsigned long get_rsp_ctx(void *);
|
extern unsigned long get_rsp_ctx(void *ctx);
|
||||||
|
|
||||||
long mcexec_uti_get_ctx(ihk_os_t os, struct uti_get_ctx_desc __user *udesc)
|
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;
|
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)
|
struct file *file)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
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 mcos_handler_info *info;
|
||||||
struct host_thread *thread;
|
struct host_thread *thread;
|
||||||
unsigned long flags;
|
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_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||||
struct mcctrl_per_proc_data *ppd;
|
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;
|
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__);
|
printk("%s: Error: copy_from_user failed\n", __FUNCTION__);
|
||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -2510,15 +2510,15 @@ long mcctrl_switch_ctx(ihk_os_t os, struct uti_save_fs_desc __user *udesc,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_fs_ctx(desc.lctx);
|
save_tls_ctx(desc.lctx);
|
||||||
info = ihk_os_get_mcos_private_data(file);
|
info = ihk_os_get_mcos_private_data(file);
|
||||||
thread = kmalloc(sizeof(struct host_thread), GFP_KERNEL);
|
thread = kmalloc(sizeof(struct host_thread), GFP_KERNEL);
|
||||||
memset(thread, '\0', sizeof(struct host_thread));
|
memset(thread, '\0', sizeof(struct host_thread));
|
||||||
thread->pid = task_tgid_vnr(current);
|
thread->pid = task_tgid_vnr(current);
|
||||||
thread->tid = task_pid_vnr(current);
|
thread->tid = task_pid_vnr(current);
|
||||||
thread->usp = (unsigned long)usp;
|
thread->usp = (unsigned long)usp;
|
||||||
thread->lfs = get_fs_ctx(desc.lctx);
|
thread->ltls = get_tls_ctx(desc.lctx);
|
||||||
thread->rfs = get_fs_ctx(desc.rctx);
|
thread->rtls = get_tls_ctx(desc.rctx);
|
||||||
thread->handler = info;
|
thread->handler = info;
|
||||||
|
|
||||||
write_lock_irqsave(&host_thread_lock, flags);
|
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);
|
read_unlock_irqrestore(&host_thread_lock, flags);
|
||||||
if (thread) {
|
if (thread) {
|
||||||
if (arg)
|
if (arg)
|
||||||
restore_fs(thread->lfs);
|
restore_tls(thread->ltls);
|
||||||
else
|
else
|
||||||
restore_fs(thread->rfs);
|
restore_tls(thread->rtls);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ret = -EINVAL;
|
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);
|
return mcexec_uti_get_ctx(os, (struct uti_get_ctx_desc *)arg);
|
||||||
|
|
||||||
case MCEXEC_UP_UTI_SWITCH_CTX:
|
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);
|
file);
|
||||||
|
|
||||||
case MCEXEC_UP_SIG_THREAD:
|
case MCEXEC_UP_SIG_THREAD:
|
||||||
|
|||||||
@@ -565,9 +565,9 @@ struct mcctrl_ioctl_getrusage_desc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* uti */
|
/* 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);
|
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 host_thread {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
@@ -575,8 +575,8 @@ struct host_thread {
|
|||||||
int pid;
|
int pid;
|
||||||
int tid;
|
int tid;
|
||||||
unsigned long usp;
|
unsigned long usp;
|
||||||
unsigned long lfs;
|
unsigned long ltls;
|
||||||
unsigned long rfs;
|
unsigned long rtls;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used to wake-up a Linux thread futex_wait()-ing */
|
/* Used to wake-up a Linux thread futex_wait()-ing */
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Syscam call convention:
|
|||||||
rsi: cmd
|
rsi: cmd
|
||||||
rdx: param
|
rdx: param
|
||||||
|
|
||||||
Save and switch the context including FS.
|
Save and switch the context including TLS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.global switch_ctx
|
.global switch_ctx
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "../include/uprotocol.h"
|
#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 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 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);
|
extern int archdep_syscall(struct syscall_wait_desc *w, long *ret);
|
||||||
|
|||||||
@@ -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)
|
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_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;
|
int rc = 0;
|
||||||
|
|
||||||
struct thread_data_s *tp;
|
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;
|
uti_desc->start_syscall_intercept = 1;
|
||||||
|
|
||||||
/* Save remote and local FS and then contex-switch */
|
/* Save remote and local FS and then contex-switch */
|
||||||
save_fs_desc.rctx = uti_desc->rctx;
|
switch_ctx_desc.rctx = uti_desc->rctx;
|
||||||
save_fs_desc.lctx = uti_desc->lctx;
|
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))
|
uti_desc->lctx, uti_desc->rctx))
|
||||||
< 0) {
|
< 0) {
|
||||||
fprintf(stderr, "%s: ERROR switch_ctx failed (%d)\n", __FUNCTION__, rc);
|
fprintf(stderr, "%s: ERROR switch_ctx failed (%d)\n", __FUNCTION__, rc);
|
||||||
|
|||||||
Reference in New Issue
Block a user