mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 23:05:39 +00:00
sigframe: prepare macro helpers for two sigframes
As on x86 compat/native sigframe differ, I need to generalize/modify sigframe macro helpers having in mind: - SIGFRAME_OFFSET differ between native/compat tasks, so it takes sigframe parameter now, which will be used in following patches (also renamed it in RT_SIGFRAME_OFFSET to complement other macros) - RT_SIGFRAME_FPU is now pointer, because each caller takes result's address with &RT_SIGFRAME_FPU(...) - sigreturn_prep_fpu_frame now takes rt_sigframe parameter, as address of fpu_state pointer on x86 will depend on native/compat frame type, so I check local sigframe's type and count address for rsigframe. (See in the very next commit). Cc: Laurent Dufour <ldufour@linux.vnet.ibm.com> Cc: Christopher Covington <cov@codeaurora.org> Cc: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
3a0c6fdd85
commit
c220f6da46
@@ -183,7 +183,7 @@ void arch_free_thread_info(CoreEntry *core)
|
||||
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
|
||||
{
|
||||
int i;
|
||||
struct fpsimd_context *fpsimd = &RT_SIGFRAME_FPU(sigframe);
|
||||
struct fpsimd_context *fpsimd = RT_SIGFRAME_FPU(sigframe);
|
||||
|
||||
if (core->ti_aarch64->fpsimd->n_vregs != 64)
|
||||
return 1;
|
||||
|
@@ -93,15 +93,21 @@ struct rt_sigframe {
|
||||
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
|
||||
#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.pc)
|
||||
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) ((struct aux_context*)&(rt_sigframe)->uc.uc_mcontext.__reserved)->fpsimd
|
||||
|
||||
#define SIGFRAME_OFFSET 0
|
||||
#define RT_SIGFRAME_AUX_CONTEXT(rt_sigframe) \
|
||||
((struct aux_context*)&(rt_sigframe)->uc.uc_mcontext.__reserved)
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) \
|
||||
(&RT_SIGFRAME_AUX_CONTEXT(rt_sigframe)->fpsimd)
|
||||
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
|
||||
|
||||
|
||||
int restore_gpregs(struct rt_sigframe *f, UserAarch64RegsEntry *r);
|
||||
int restore_nonsigframe_gpregs(UserAarch64RegsEntry *r);
|
||||
|
||||
static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_state) { return 0; }
|
||||
static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
|
||||
struct rt_sigframe *rsigframe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void restore_tls(tls_t *ptls)
|
||||
{
|
||||
|
@@ -126,15 +126,21 @@ struct rt_sigframe {
|
||||
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->sig.uc)
|
||||
#define RT_SIGFRAME_REGIP(rt_sigframe) (rt_sigframe)->sig.uc.uc_mcontext.arm_ip
|
||||
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) 1
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) ((struct aux_sigframe *)&rt_sigframe->sig.uc.uc_regspace)->vfp
|
||||
|
||||
#define SIGFRAME_OFFSET 0
|
||||
#define RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe) \
|
||||
((struct aux_sigframe *)&(rt_sigframe)->sig.uc.uc_regspace)
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) \
|
||||
(&RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe)->vfp)
|
||||
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
|
||||
|
||||
|
||||
int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r);
|
||||
int restore_nonsigframe_gpregs(UserArmRegsEntry *r);
|
||||
|
||||
static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_state) { return 0; }
|
||||
static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
|
||||
struct rt_sigframe *rsigframe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void restore_tls(tls_t *ptls) {
|
||||
asm (
|
||||
|
@@ -471,9 +471,11 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
|
||||
* used in the context of the checkpointed process, the v_regs pointer in the
|
||||
* signal frame must be updated to match the address in the remote stack.
|
||||
*/
|
||||
int sigreturn_prep_fpu_frame(struct rt_sigframe *frame, mcontext_t *rcontext)
|
||||
int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
|
||||
struct rt_sigframe *rframe)
|
||||
{
|
||||
mcontext_t *lcontext = &frame->uc.uc_mcontext;
|
||||
mcontext_t *rcontext = RT_SIGFRAME_FPU(rframe);
|
||||
mcontext_t *lcontext = RT_SIGFRAME_FPU(frame);
|
||||
|
||||
if (lcontext->v_regs) {
|
||||
uint64_t offset = (uint64_t)(lcontext->v_regs) - (uint64_t)lcontext;
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#define rt_sigcontext sigcontext
|
||||
|
||||
#include "sigframe.h"
|
||||
#define SIGFRAME_OFFSET 0
|
||||
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
|
||||
|
||||
/* Copied from the Linux kernel header arch/powerpc/include/asm/ptrace.h */
|
||||
#define USER_REDZONE_SIZE 512
|
||||
@@ -104,7 +104,7 @@ struct rt_sigframe {
|
||||
#define RT_SIGFRAME_UC(rt_sigframe) (&(rt_sigframe)->uc)
|
||||
#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.gp_regs[PT_NIP])
|
||||
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) ((rt_sigframe)->uc.uc_mcontext)
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) (&(rt_sigframe)->uc.uc_mcontext)
|
||||
|
||||
int restore_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r);
|
||||
int restore_nonsigframe_gpregs(UserPpc64RegsEntry *r);
|
||||
@@ -123,7 +123,7 @@ static inline int ptrace_flush_breakpoints(pid_t pid)
|
||||
}
|
||||
|
||||
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
|
||||
mcontext_t *sigcontext);
|
||||
struct rt_sigframe *rframe);
|
||||
|
||||
/*
|
||||
* Defined in arch/ppc64/syscall-common-ppc64.S
|
||||
|
@@ -499,8 +499,10 @@ int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_state)
|
||||
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
|
||||
struct rt_sigframe *rsigframe)
|
||||
{
|
||||
fpu_state_t *fpu_state = RT_SIGFRAME_FPU(rsigframe);
|
||||
unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
|
||||
|
||||
if ((addr % 64ul) == 0ul) {
|
||||
|
@@ -137,15 +137,16 @@ struct rt_sigframe {
|
||||
|
||||
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
|
||||
#define RT_SIGFRAME_REGIP(rt_sigframe) (rt_sigframe)->uc.uc_mcontext.rip
|
||||
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (rt_sigframe)->fpu_state.has_fpu
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) (rt_sigframe)->fpu_state
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) (&(rt_sigframe)->fpu_state)
|
||||
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (RT_SIGFRAME_FPU(rt_sigframe)->has_fpu)
|
||||
|
||||
#define SIGFRAME_OFFSET 8
|
||||
#define RT_SIGFRAME_OFFSET(rt_sigframe) 8
|
||||
|
||||
int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r);
|
||||
int restore_nonsigframe_gpregs(UserX86RegsEntry *r);
|
||||
|
||||
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_state);
|
||||
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
|
||||
struct rt_sigframe *rsigframe);
|
||||
|
||||
static inline void restore_tls(tls_t *ptls) { (void)ptls; }
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
struct rt_sigframe;
|
||||
|
||||
#ifndef SIGFRAME_MAX_OFFSET
|
||||
#define SIGFRAME_MAX_OFFSET SIGFRAME_OFFSET
|
||||
#define SIGFRAME_MAX_OFFSET RT_SIGFRAME_OFFSET(0)
|
||||
#endif
|
||||
|
||||
/* sigframe should be aligned on 64 byte for x86 and 8 bytes for arm */
|
||||
|
@@ -614,7 +614,7 @@ static int fini()
|
||||
mprotect_vmas(mprotect_args);
|
||||
}
|
||||
|
||||
new_sp = (long)sigframe + SIGFRAME_OFFSET;
|
||||
new_sp = (long)sigframe + RT_SIGFRAME_OFFSET(sigframe);
|
||||
pr_debug("%ld: new_sp=%lx ip %lx\n", sys_gettid(),
|
||||
new_sp, RT_SIGFRAME_REGIP(sigframe));
|
||||
|
||||
|
@@ -482,7 +482,7 @@ long __export_restore_thread(struct thread_restore_args *args)
|
||||
|
||||
futex_dec_and_wake(&thread_inprogress);
|
||||
|
||||
new_sp = (long)rt_sigframe + SIGFRAME_OFFSET;
|
||||
new_sp = (long)rt_sigframe + RT_SIGFRAME_OFFSET(rt_sigframe);
|
||||
rst_sigreturn(new_sp);
|
||||
|
||||
core_restore_end:
|
||||
@@ -1432,7 +1432,7 @@ long __export_restore_task(struct task_restore_args *args)
|
||||
/*
|
||||
* Sigframe stack.
|
||||
*/
|
||||
new_sp = (long)rt_sigframe + SIGFRAME_OFFSET;
|
||||
new_sp = (long)rt_sigframe + RT_SIGFRAME_OFFSET(rt_sigframe);
|
||||
|
||||
/*
|
||||
* Prepare the stack and call for sigreturn,
|
||||
|
@@ -18,11 +18,14 @@ static inline void setup_sas(struct rt_sigframe* sigframe, ThreadSasEntry *sas)
|
||||
}
|
||||
}
|
||||
|
||||
#define RT_SIGFRAME_UC_SIGMASK(sigframe) \
|
||||
(k_rtsigset_t*)&RT_SIGFRAME_UC(sigframe)->uc_sigmask
|
||||
|
||||
int construct_sigframe(struct rt_sigframe *sigframe,
|
||||
struct rt_sigframe *rsigframe,
|
||||
CoreEntry *core)
|
||||
{
|
||||
k_rtsigset_t *blk_sigset = (k_rtsigset_t*)&RT_SIGFRAME_UC(sigframe)->uc_sigmask;
|
||||
k_rtsigset_t *blk_sigset = RT_SIGFRAME_UC_SIGMASK(sigframe);
|
||||
|
||||
if (core->tc)
|
||||
memcpy(blk_sigset, &core->tc->blk_sigset, sizeof(k_rtsigset_t));
|
||||
@@ -36,7 +39,7 @@ int construct_sigframe(struct rt_sigframe *sigframe,
|
||||
return -1;
|
||||
|
||||
if (RT_SIGFRAME_HAS_FPU(sigframe))
|
||||
if (sigreturn_prep_fpu_frame(sigframe, &RT_SIGFRAME_FPU(rsigframe)))
|
||||
if (sigreturn_prep_fpu_frame(sigframe, rsigframe))
|
||||
return -1;
|
||||
|
||||
if (restore_gpregs(sigframe, CORE_THREAD_ARCH_INFO(core)->gpregs))
|
||||
|
Reference in New Issue
Block a user