[CRIU] [PATCHv1 04/26] sigframe: prepare macro helpers for two sigframes

Laurent Dufour ldufour at linux.vnet.ibm.com
Thu Jun 16 06:34:19 PDT 2016


On 16/06/2016 12:53, Dmitry Safonov wrote:
> 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).
> 

Hi Dimitry,

I've trouble applying your series on top of criu-dev (commit 674583f20cb6).
I'd like to apply to it and give it a try before stating...

Could you rebase it ?

Cheers,
Laurent.


> Cc: Laurent Dufour <ldufour at linux.vnet.ibm.com>
> Cc: Christopher Covington <cov at codeaurora.org>
> Cc: Cyrill Gorcunov <gorcunov at openvz.org>
> Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
> ---
>  criu/arch/aarch64/crtools.c              |  2 +-
>  criu/arch/aarch64/include/asm/restorer.h | 14 ++++++++++----
>  criu/arch/arm/include/asm/restorer.h     | 14 ++++++++++----
>  criu/arch/ppc64/crtools.c                |  6 ++++--
>  criu/arch/ppc64/include/asm/restorer.h   |  6 +++---
>  criu/arch/x86/crtools.c                  |  4 +++-
>  criu/arch/x86/include/asm/restorer.h     |  9 +++++----
>  criu/include/sigframe.h                  |  2 +-
>  criu/pie/parasite.c                      |  2 +-
>  criu/pie/restorer.c                      |  4 ++--
>  criu/sigframe.c                          |  7 +++++--
>  11 files changed, 45 insertions(+), 25 deletions(-)
> 
> diff --git a/criu/arch/aarch64/crtools.c b/criu/arch/aarch64/crtools.c
> index 15345eca02e9..e131498f2bb6 100644
> --- a/criu/arch/aarch64/crtools.c
> +++ b/criu/arch/aarch64/crtools.c
> @@ -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;
> diff --git a/criu/arch/aarch64/include/asm/restorer.h b/criu/arch/aarch64/include/asm/restorer.h
> index b96f83b04a1c..57ccfddcd103 100644
> --- a/criu/arch/aarch64/include/asm/restorer.h
> +++ b/criu/arch/aarch64/include/asm/restorer.h
> @@ -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)
>  {
> diff --git a/criu/arch/arm/include/asm/restorer.h b/criu/arch/arm/include/asm/restorer.h
> index 2c6d6aedefe9..2da417206cc3 100644
> --- a/criu/arch/arm/include/asm/restorer.h
> +++ b/criu/arch/arm/include/asm/restorer.h
> @@ -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 (
> diff --git a/criu/arch/ppc64/crtools.c b/criu/arch/ppc64/crtools.c
> index 77e4146bc320..3cf55f0fd9c1 100644
> --- a/criu/arch/ppc64/crtools.c
> +++ b/criu/arch/ppc64/crtools.c
> @@ -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;
> diff --git a/criu/arch/ppc64/include/asm/restorer.h b/criu/arch/ppc64/include/asm/restorer.h
> index 1400ff3463ea..d7e20ca7d83c 100644
> --- a/criu/arch/ppc64/include/asm/restorer.h
> +++ b/criu/arch/ppc64/include/asm/restorer.h
> @@ -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
> diff --git a/criu/arch/x86/crtools.c b/criu/arch/x86/crtools.c
> index 991032f722d0..b33764a9ad4c 100644
> --- a/criu/arch/x86/crtools.c
> +++ b/criu/arch/x86/crtools.c
> @@ -616,8 +616,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) {
> diff --git a/criu/arch/x86/include/asm/restorer.h b/criu/arch/x86/include/asm/restorer.h
> index d8ecae6ad0a3..3c17fc67516b 100644
> --- a/criu/arch/x86/include/asm/restorer.h
> +++ b/criu/arch/x86/include/asm/restorer.h
> @@ -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; }
> 
> diff --git a/criu/include/sigframe.h b/criu/include/sigframe.h
> index b98323182d5f..6ee5fd766449 100644
> --- a/criu/include/sigframe.h
> +++ b/criu/include/sigframe.h
> @@ -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 */
> diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
> index 4e8683de2b04..da47319d9356 100644
> --- a/criu/pie/parasite.c
> +++ b/criu/pie/parasite.c
> @@ -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));
> 
> diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
> index 5910fd02ecad..a2076c3193c3 100644
> --- a/criu/pie/restorer.c
> +++ b/criu/pie/restorer.c
> @@ -489,7 +489,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:
> @@ -1492,7 +1492,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,
> diff --git a/criu/sigframe.c b/criu/sigframe.c
> index 2a220ce5dfba..72eaee965ecf 100644
> --- a/criu/sigframe.c
> +++ b/criu/sigframe.c
> @@ -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))
> 



More information about the CRIU mailing list