Commit c220f6da authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Pavel Emelyanov

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: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 3a0c6fdd
...@@ -183,7 +183,7 @@ void arch_free_thread_info(CoreEntry *core) ...@@ -183,7 +183,7 @@ void arch_free_thread_info(CoreEntry *core)
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core) int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
{ {
int i; 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) if (core->ti_aarch64->fpsimd->n_vregs != 64)
return 1; return 1;
......
...@@ -93,15 +93,21 @@ struct rt_sigframe { ...@@ -93,15 +93,21 @@ struct rt_sigframe {
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc) #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_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.pc)
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1) #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 RT_SIGFRAME_AUX_CONTEXT(rt_sigframe) \
((struct aux_context*)&(rt_sigframe)->uc.uc_mcontext.__reserved)
#define SIGFRAME_OFFSET 0 #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_gpregs(struct rt_sigframe *f, UserAarch64RegsEntry *r);
int restore_nonsigframe_gpregs(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) static inline void restore_tls(tls_t *ptls)
{ {
......
...@@ -126,15 +126,21 @@ struct rt_sigframe { ...@@ -126,15 +126,21 @@ struct rt_sigframe {
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->sig.uc) #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_REGIP(rt_sigframe) (rt_sigframe)->sig.uc.uc_mcontext.arm_ip
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) 1 #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 RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe) \
((struct aux_sigframe *)&(rt_sigframe)->sig.uc.uc_regspace)
#define SIGFRAME_OFFSET 0 #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_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r);
int restore_nonsigframe_gpregs(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) { static inline void restore_tls(tls_t *ptls) {
asm ( asm (
......
...@@ -471,9 +471,11 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core) ...@@ -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 * 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. * 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) { if (lcontext->v_regs) {
uint64_t offset = (uint64_t)(lcontext->v_regs) - (uint64_t)lcontext; uint64_t offset = (uint64_t)(lcontext->v_regs) - (uint64_t)lcontext;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#define rt_sigcontext sigcontext #define rt_sigcontext sigcontext
#include "sigframe.h" #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 */ /* Copied from the Linux kernel header arch/powerpc/include/asm/ptrace.h */
#define USER_REDZONE_SIZE 512 #define USER_REDZONE_SIZE 512
...@@ -104,7 +104,7 @@ struct rt_sigframe { ...@@ -104,7 +104,7 @@ struct rt_sigframe {
#define RT_SIGFRAME_UC(rt_sigframe) (&(rt_sigframe)->uc) #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_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_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_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r);
int restore_nonsigframe_gpregs(UserPpc64RegsEntry *r); int restore_nonsigframe_gpregs(UserPpc64RegsEntry *r);
...@@ -123,7 +123,7 @@ static inline int ptrace_flush_breakpoints(pid_t pid) ...@@ -123,7 +123,7 @@ static inline int ptrace_flush_breakpoints(pid_t pid)
} }
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
mcontext_t *sigcontext); struct rt_sigframe *rframe);
/* /*
* Defined in arch/ppc64/syscall-common-ppc64.S * Defined in arch/ppc64/syscall-common-ppc64.S
......
...@@ -499,8 +499,10 @@ int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r) ...@@ -499,8 +499,10 @@ int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
return 0; 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; unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
if ((addr % 64ul) == 0ul) { if ((addr % 64ul) == 0ul) {
......
...@@ -137,15 +137,16 @@ struct rt_sigframe { ...@@ -137,15 +137,16 @@ struct rt_sigframe {
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc) #define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) (rt_sigframe)->uc.uc_mcontext.rip #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_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r);
int restore_nonsigframe_gpregs(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; } static inline void restore_tls(tls_t *ptls) { (void)ptls; }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
struct rt_sigframe; struct rt_sigframe;
#ifndef SIGFRAME_MAX_OFFSET #ifndef SIGFRAME_MAX_OFFSET
#define SIGFRAME_MAX_OFFSET SIGFRAME_OFFSET #define SIGFRAME_MAX_OFFSET RT_SIGFRAME_OFFSET(0)
#endif #endif
/* sigframe should be aligned on 64 byte for x86 and 8 bytes for arm */ /* sigframe should be aligned on 64 byte for x86 and 8 bytes for arm */
......
...@@ -614,7 +614,7 @@ static int fini() ...@@ -614,7 +614,7 @@ static int fini()
mprotect_vmas(mprotect_args); 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(), pr_debug("%ld: new_sp=%lx ip %lx\n", sys_gettid(),
new_sp, RT_SIGFRAME_REGIP(sigframe)); new_sp, RT_SIGFRAME_REGIP(sigframe));
......
...@@ -482,7 +482,7 @@ long __export_restore_thread(struct thread_restore_args *args) ...@@ -482,7 +482,7 @@ long __export_restore_thread(struct thread_restore_args *args)
futex_dec_and_wake(&thread_inprogress); 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); rst_sigreturn(new_sp);
core_restore_end: core_restore_end:
...@@ -1432,7 +1432,7 @@ long __export_restore_task(struct task_restore_args *args) ...@@ -1432,7 +1432,7 @@ long __export_restore_task(struct task_restore_args *args)
/* /*
* Sigframe stack. * 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, * Prepare the stack and call for sigreturn,
......
...@@ -18,11 +18,14 @@ static inline void setup_sas(struct rt_sigframe* sigframe, ThreadSasEntry *sas) ...@@ -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, int construct_sigframe(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe, struct rt_sigframe *rsigframe,
CoreEntry *core) 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) if (core->tc)
memcpy(blk_sigset, &core->tc->blk_sigset, sizeof(k_rtsigset_t)); memcpy(blk_sigset, &core->tc->blk_sigset, sizeof(k_rtsigset_t));
...@@ -36,7 +39,7 @@ int construct_sigframe(struct rt_sigframe *sigframe, ...@@ -36,7 +39,7 @@ int construct_sigframe(struct rt_sigframe *sigframe,
return -1; return -1;
if (RT_SIGFRAME_HAS_FPU(sigframe)) 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; return -1;
if (restore_gpregs(sigframe, CORE_THREAD_ARCH_INFO(core)->gpregs)) if (restore_gpregs(sigframe, CORE_THREAD_ARCH_INFO(core)->gpregs))
......
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