Commit f1228904 authored by Pavel Emelyanov's avatar Pavel Emelyanov

rst: Merge registers restoring code for task and threads restore

Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 1bc50df9
...@@ -143,15 +143,61 @@ static void restore_sched_info(struct rst_sched_param *p) ...@@ -143,15 +143,61 @@ static void restore_sched_info(struct rst_sched_param *p)
sys_sched_setscheduler(0, p->policy, &parm); sys_sched_setscheduler(0, p->policy, &parm);
} }
static int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
{
long ret;
unsigned long fsgs_base;
#define CPREG1(d) f->uc.uc_mcontext.d = r->d
#define CPREG2(d, s) f->uc.uc_mcontext.d = r->s
CPREG1(r8);
CPREG1(r9);
CPREG1(r10);
CPREG1(r11);
CPREG1(r12);
CPREG1(r13);
CPREG1(r14);
CPREG1(r15);
CPREG2(rdi, di);
CPREG2(rsi, si);
CPREG2(rbp, bp);
CPREG2(rbx, bx);
CPREG2(rdx, dx);
CPREG2(rax, ax);
CPREG2(rcx, cx);
CPREG2(rsp, sp);
CPREG2(rip, ip);
CPREG2(eflags, flags);
CPREG1(cs);
CPREG1(gs);
CPREG1(fs);
fsgs_base = r->fs_base;
ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base);
if (ret) {
pr_info("SET_FS fail %ld\n", ret);
return -1;
}
fsgs_base = r->gs_base;
ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base);
if (ret) {
pr_info("SET_GS fail %ld\n", ret);
return -1;
}
return 0;
}
/* /*
* Threads restoration via sigreturn. Note it's locked * Threads restoration via sigreturn. Note it's locked
* routine and calls for unlock at the end. * routine and calls for unlock at the end.
*/ */
long __export_restore_thread(struct thread_restore_args *args) long __export_restore_thread(struct thread_restore_args *args)
{ {
long ret = -1;
struct rt_sigframe *rt_sigframe; struct rt_sigframe *rt_sigframe;
unsigned long new_sp, fsgs_base; unsigned long new_sp;
int my_pid = sys_gettid(); int my_pid = sys_gettid();
if (my_pid != args->pid) { if (my_pid != args->pid) {
...@@ -172,44 +218,8 @@ long __export_restore_thread(struct thread_restore_args *args) ...@@ -172,44 +218,8 @@ long __export_restore_thread(struct thread_restore_args *args)
rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8; rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8;
#define CPREGT1(d) rt_sigframe->uc.uc_mcontext.d = args->gpregs.d if (restore_gpregs(rt_sigframe, &args->gpregs))
#define CPREGT2(d, s) rt_sigframe->uc.uc_mcontext.d = args->gpregs.s
CPREGT1(r8);
CPREGT1(r9);
CPREGT1(r10);
CPREGT1(r11);
CPREGT1(r12);
CPREGT1(r13);
CPREGT1(r14);
CPREGT1(r15);
CPREGT2(rdi, di);
CPREGT2(rsi, si);
CPREGT2(rbp, bp);
CPREGT2(rbx, bx);
CPREGT2(rdx, dx);
CPREGT2(rax, ax);
CPREGT2(rcx, cx);
CPREGT2(rsp, sp);
CPREGT2(rip, ip);
CPREGT2(eflags, flags);
CPREGT1(cs);
CPREGT1(gs);
CPREGT1(fs);
fsgs_base = args->gpregs.fs_base;
ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base);
if (ret) {
pr_err("SET_FS fail %ld\n", ret);
goto core_restore_end;
}
fsgs_base = args->gpregs.gs_base;
ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base);
if (ret) {
pr_err("SET_GS fail %ld\n", ret);
goto core_restore_end; goto core_restore_end;
}
mutex_unlock(args->rst_lock); mutex_unlock(args->rst_lock);
...@@ -321,7 +331,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -321,7 +331,7 @@ long __export_restore_task(struct task_restore_core_args *args)
u64 va; u64 va;
struct rt_sigframe *rt_sigframe; struct rt_sigframe *rt_sigframe;
unsigned long new_sp, fsgs_base; unsigned long new_sp;
pid_t my_pid = sys_getpid(); pid_t my_pid = sys_getpid();
rt_sigaction_t act; rt_sigaction_t act;
...@@ -495,44 +505,9 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -495,44 +505,9 @@ long __export_restore_task(struct task_restore_core_args *args)
*/ */
rt_sigframe = (void *)args->t.mem_zone.rt_sigframe + 8; rt_sigframe = (void *)args->t.mem_zone.rt_sigframe + 8;
#define CPREG1(d) rt_sigframe->uc.uc_mcontext.d = args->t.gpregs.d if (restore_gpregs(rt_sigframe, &args->t.gpregs))
#define CPREG2(d, s) rt_sigframe->uc.uc_mcontext.d = args->t.gpregs.s
CPREG1(r8);
CPREG1(r9);
CPREG1(r10);
CPREG1(r11);
CPREG1(r12);
CPREG1(r13);
CPREG1(r14);
CPREG1(r15);
CPREG2(rdi, di);
CPREG2(rsi, si);
CPREG2(rbp, bp);
CPREG2(rbx, bx);
CPREG2(rdx, dx);
CPREG2(rax, ax);
CPREG2(rcx, cx);
CPREG2(rsp, sp);
CPREG2(rip, ip);
CPREG2(eflags, flags);
CPREG1(cs);
CPREG1(gs);
CPREG1(fs);
fsgs_base = args->t.gpregs.fs_base;
ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base);
if (ret) {
pr_info("SET_FS fail %ld\n", ret);
goto core_restore_end; goto core_restore_end;
}
fsgs_base = args->t.gpregs.gs_base;
ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base);
if (ret) {
pr_info("SET_GS fail %ld\n", ret);
goto core_restore_end;
}
/* /*
* Blocked signals. * Blocked signals.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment