arm64: uti: Add arch-dependent helper for context switch

arm64 performs context-switch in kernel space instead of user space as in
x86_64.

Change-Id: Ib119b9ff014effb970183ee86cfac67fab773cba
Futjitsu: POSTK_DEBUG_ARCH_DEP_99
This commit is contained in:
Shiratori, Takehiro
2019-03-12 14:19:18 +09:00
committed by Masamichi Takagi
parent 63d500515a
commit 8356ef6c96
9 changed files with 91 additions and 47 deletions

View File

@ -1,7 +1,12 @@
/* archdeps.c COPYRIGHT FUJITSU LIMITED 2016 */
/* archdeps.c COPYRIGHT FUJITSU LIMITED 2016-2019 */
#include <linux/version.h>
#include <linux/mm_types.h>
#include <linux/kallsyms.h>
#if KERNEL_VERSION(4, 11, 0) <= LINUX_VERSION_CODE
#include <linux/sched/task_stack.h>
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
#include <linux/ptrace.h>
#include <linux/uaccess.h>
#include <asm/vdso.h>
#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(&current_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;
}