Commit 22396f76 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

restore: construct sigframe in crtools

Before this patch sigframes were constructed in restorer. We are going
to construct sigframes for parasites. Both parasite and restorer should
be as thing as posible.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 45233b5e
......@@ -2,6 +2,7 @@
#include <unistd.h>
#include "asm/types.h"
#include "asm/restorer.h"
#include "compiler.h"
#include "ptrace.h"
#include "asm/processor-flags.h"
......@@ -232,3 +233,43 @@ void *mmap_seized(struct parasite_ctl *ctl,
return (void *)map;
}
int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r)
{
#define CPREG1(d) f->sig.uc.uc_mcontext.arm_##d = r->d
#define CPREG2(d, s) f->sig.uc.uc_mcontext.arm_##d = r->s
CPREG1(r0);
CPREG1(r1);
CPREG1(r2);
CPREG1(r3);
CPREG1(r4);
CPREG1(r5);
CPREG1(r6);
CPREG1(r7);
CPREG1(r8);
CPREG1(r9);
CPREG1(r10);
CPREG1(fp);
CPREG1(ip);
CPREG1(sp);
CPREG1(lr);
CPREG1(pc);
CPREG1(cpsr);
#undef CPREG1
#undef CPREG2
return 0;
}
int restore_fpu(struct rt_sigframe *sigframe, fpu_state_t *fpu_state)
{
struct aux_sigframe *aux = (struct aux_sigframe *)&sigframe->sig.uc.uc_regspace;
aux->vfp.magic = VFP_MAGIC;
aux->vfp.size = VFP_STORAGE_SIZE;
builtin_memcpy(&aux->vfp.ufp, &fpu_state->ufp, sizeof(aux->vfp.ufp));
return 0;
}
......@@ -9,47 +9,7 @@
#include "asm/fpu.h"
#include "cpu.h"
int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r)
{
#define CPREG1(d) f->sig.uc.uc_mcontext.arm_##d = r->d
#define CPREG2(d, s) f->sig.uc.uc_mcontext.arm_##d = r->s
CPREG1(r0);
CPREG1(r1);
CPREG1(r2);
CPREG1(r3);
CPREG1(r4);
CPREG1(r5);
CPREG1(r6);
CPREG1(r7);
CPREG1(r8);
CPREG1(r9);
CPREG1(r10);
CPREG1(fp);
CPREG1(ip);
CPREG1(sp);
CPREG1(lr);
CPREG1(pc);
CPREG1(cpsr);
#undef CPREG1
#undef CPREG2
return 0;
}
int restore_nonsigframe_gpregs(UserArmRegsEntry *r)
{
return 0;
}
int restore_fpu(struct rt_sigframe *sigframe, fpu_state_t *fpu_state)
{
struct aux_sigframe *aux = (struct aux_sigframe *)&sigframe->sig.uc.uc_regspace;
aux->vfp.magic = VFP_MAGIC;
aux->vfp.size = VFP_STORAGE_SIZE;
builtin_memcpy(&aux->vfp.ufp, &fpu_state->ufp, sizeof(aux->vfp.ufp));
return 0;
}
......@@ -3,6 +3,7 @@
#include <elf.h>
#include "asm/processor-flags.h"
#include "asm/restorer.h"
#include "asm/types.h"
#include "asm/fpu.h"
......@@ -454,3 +455,48 @@ void *mmap_seized(struct parasite_ctl *ctl,
return (void *)map;
}
int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
{
#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);
return 0;
}
int restore_fpu(struct rt_sigframe *sigframe, fpu_state_t *fpu_state)
{
unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
if ((addr % 64ul) == 0ul) {
sigframe->uc.uc_mcontext.fpstate = &fpu_state->xsave;
} else {
pr_err("Unaligned address passed: %lx\n", addr);
return -1;
}
return 0;
}
......@@ -2,6 +2,7 @@
#define __CR_ASM_RESTORER_H__
#include "asm/types.h"
#include "asm/fpu.h"
#include "protobuf/core.pb-c.h"
struct pt_regs {
......
......@@ -8,36 +8,6 @@
#include "log.h"
#include "cpu.h"
int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
{
#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);
return 0;
}
int restore_nonsigframe_gpregs(UserX86RegsEntry *r)
{
long ret;
......@@ -59,20 +29,3 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r)
return 0;
}
int restore_fpu(struct rt_sigframe *sigframe, fpu_state_t *fpu_state)
{
unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
if (!fpu_state->has_fpu)
return 0;
if ((addr % 64ul) == 0ul) {
sigframe->uc.uc_mcontext.fpstate = &fpu_state->xsave;
} else {
pr_err("Unaligned address passed: %lx\n", addr);
return -1;
}
return 0;
}
......@@ -26,6 +26,7 @@
#include "compiler.h"
#include "asm/types.h"
#include "asm/restorer.h"
#include "image.h"
#include "util.h"
......@@ -1997,6 +1998,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
for (i = 0; i < current->nr_threads; i++) {
int fd_core;
CoreEntry *tcore;
struct rt_sigframe *sigframe;
thread_args[i].pid = current->threads[i].virt;
thread_args[i].siginfo_nr = siginfo_priv_nr[i];
......@@ -2040,16 +2042,15 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
thread_args[i].has_futex = true;
thread_args[i].futex_rla = tcore->thread_core->futex_rla;
thread_args[i].futex_rla_len = tcore->thread_core->futex_rla_len;
thread_args[i].has_blk_sigset = tcore->thread_core->has_blk_sigset;
memcpy(&thread_args[i].blk_sigset,
&tcore->thread_core->blk_sigset, sizeof(k_rtsigset_t));
ret = prep_sched_info(&thread_args[i].sp, tcore->thread_core);
if (ret)
goto err;
}
if (sigreturn_prep_fpu_frame(&thread_args[i].fpu_state, tcore))
sigframe = (struct rt_sigframe *)thread_args[i].mem_zone.rt_sigframe;
if (construct_sigframe(sigframe, sigframe, tcore))
goto err;
if (thread_args[i].pid != pid)
......@@ -2062,9 +2063,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
}
memcpy(&task_args->t->blk_sigset, &core->tc->blk_sigset, sizeof(k_rtsigset_t));
task_args->t->has_blk_sigset = true;
/*
* Restorer needs own copy of vdso parameters. Runtime
* vdso must be kept non intersecting with anything else,
......
......@@ -73,15 +73,10 @@ struct thread_restore_args {
u64 futex_rla;
u32 futex_rla_len;
bool has_blk_sigset;
k_rtsigset_t blk_sigset;
struct rst_sched_param sp;
struct task_restore_core_args *ta;
fpu_state_t fpu_state;
u32 tls;
siginfo_t *siginfo;
......
......@@ -35,4 +35,8 @@ struct rt_ucontext {
unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
};
struct rt_sigframe;
int construct_sigframe(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe,
CoreEntry *core);
#endif
......@@ -258,17 +258,8 @@ static int restore_thread_common(struct rt_sigframe *sigframe,
}
}
if (args->has_blk_sigset)
RT_SIGFRAME_UC(sigframe).uc_sigmask = args->blk_sigset;
restore_sched_info(&args->sp);
if (restore_fpu(sigframe, &args->fpu_state))
return -1;
if (restore_gpregs(sigframe, &args->gpregs))
return -1;
if (restore_nonsigframe_gpregs(&args->gpregs))
return -1;
......@@ -293,7 +284,7 @@ long __export_restore_thread(struct thread_restore_args *args)
goto core_restore_end;
}
rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8;
rt_sigframe = (void *)args->mem_zone.rt_sigframe;
if (restore_thread_common(rt_sigframe, args))
goto core_restore_end;
......@@ -736,7 +727,7 @@ long __export_restore_task(struct task_restore_core_args *args)
* registers from the frame, set them up and
* finally pass execution to the new IP.
*/
rt_sigframe = (void *)args->t->mem_zone.rt_sigframe + 8;
rt_sigframe = (void *)args->t->mem_zone.rt_sigframe;
if (restore_thread_common(rt_sigframe, args->t))
goto core_restore_end;
......
......@@ -6,7 +6,7 @@
#include "protobuf/core.pb-c.h"
static inline int construct_sigframe(struct rt_sigframe *sigframe,
int construct_sigframe(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe,
CoreEntry *core)
{
......@@ -20,11 +20,13 @@ static inline int construct_sigframe(struct rt_sigframe *sigframe,
} else
memset(blk_sigset, 0, sizeof(k_rtsigset_t));
sigframe->fpu_state.has_fpu = true;
if (sigreturn_prep_fpu_frame(&sigframe->fpu_state, core))
return -1;
if (restore_fpu(sigframe, &rsigframe->fpu_state))
return -1;
if (sigframe->fpu_state.has_fpu)
if (restore_fpu(sigframe, &rsigframe->fpu_state))
return -1;
if (restore_gpregs(sigframe, CORE_THREAD_ARCH_INFO(core)->gpregs))
return -1;
......
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