[CRIU] [PATCH 1/2] cr: generalized the prototype of the routine restore_fpu()

Andrew Vagin avagin at gmail.com
Sat Jun 1 10:03:22 EDT 2013


On Sat, Jun 01, 2013 at 05:37:12PM +0400, Alexander Kartashov wrote:
> A struct sigframe* instead of fpu_state_t should be passed
> to the routine restore_fpu() since FPU registers are stored
> in different fields of the sigframe in different architectures.
> An architecture-specific implementation of the routine restore_fpu()
> should know details of this layout instead of construct_sigframe().
> 
> This change makes it possible to move ARM FPU restoration
> from sigreturn_prep_fpu_frame() (where it caused a segfault
> since the pointer fpu_stat has become invalid in the dumper
> address space) to restore_fpu()
> 
> Signed-off-by: Alexander Kartashov <alekskartashov at parallels.com>
> Cc: Andrey Vagin <avagin at openvz.org>

Acked-by: Andrey Vagin <avagin at openvz.org>

> ---
>  arch/arm/crtools.c             |    9 +++++----
>  arch/arm/include/asm/restore.h |    2 +-
>  arch/x86/crtools.c             |    3 ++-
>  arch/x86/include/asm/restore.h |    2 +-
>  sigframe.c                     |    2 +-
>  5 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/crtools.c b/arch/arm/crtools.c
> index 721b37d..a5acf3b 100644
> --- a/arch/arm/crtools.c
> +++ b/arch/arm/crtools.c
> @@ -197,10 +197,12 @@ void arch_free_thread_info(CoreEntry *core)
>  	}
>  }
>  
> -int restore_fpu(fpu_state_t *fpu_state, CoreEntry *core)
> +int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
>  {
> -	memcpy(fpu_state->ufp.fpregs, CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs,
> -		sizeof(fpu_state->ufp.fpregs));
> +	struct aux_sigframe *aux = (struct aux_sigframe *)&sigframe->sig.uc.uc_regspace;
> +	fpu_state_t *fpu_state = &sigframe->fpu_state;
> +
> +	memcpy(&aux->vfp.ufp, CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, sizeof(aux->vfp.ufp));
>  	fpu_state->ufp.fpscr = CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr;
>  
>  	return 0;
> @@ -259,7 +261,6 @@ int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_stat
>  
>  	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;
>  }
> diff --git a/arch/arm/include/asm/restore.h b/arch/arm/include/asm/restore.h
> index 87b9e2b..c1ef1fe 100644
> --- a/arch/arm/include/asm/restore.h
> +++ b/arch/arm/include/asm/restore.h
> @@ -20,6 +20,6 @@ static inline void core_get_tls(CoreEntry *pcore, u32 *ptls)
>  }
>  
>  
> -int restore_fpu(fpu_state_t *fpu_state, CoreEntry *core);
> +int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core);
>  
>  #endif
> diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c
> index b565ad9..71d3c36 100644
> --- a/arch/x86/crtools.c
> +++ b/arch/x86/crtools.c
> @@ -373,8 +373,9 @@ static void show_rt_xsave_frame(struct xsave_struct *x)
>  	pr_debug("-----------------------\n");
>  }
>  
> -int restore_fpu(fpu_state_t *fpu_state, CoreEntry *core)
> +int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
>  {
> +	fpu_state_t *fpu_state = &sigframe->fpu_state;
>  	struct xsave_struct *x = &fpu_state->xsave;
>  
>  	/*
> diff --git a/arch/x86/include/asm/restore.h b/arch/x86/include/asm/restore.h
> index 3394507..c0a1ff8 100644
> --- a/arch/x86/include/asm/restore.h
> +++ b/arch/x86/include/asm/restore.h
> @@ -18,6 +18,6 @@
>  #define core_get_tls(pcore, ptls)
>  
>  
> -int restore_fpu(fpu_state_t *fpu_state, CoreEntry *core);
> +int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core);
>  
>  #endif
> diff --git a/sigframe.c b/sigframe.c
> index c260aa4..68c9776 100644
> --- a/sigframe.c
> +++ b/sigframe.c
> @@ -21,7 +21,7 @@ int construct_sigframe(struct rt_sigframe *sigframe,
>  		memset(blk_sigset, 0, sizeof(k_rtsigset_t));
>  
>  	sigframe->fpu_state.has_fpu = true;
> -	if (restore_fpu(&sigframe->fpu_state, core))
> +	if (restore_fpu(sigframe, core))
>  		return -1;
>  
>  	if (sigframe->fpu_state.has_fpu)
> -- 
> 1.7.10.4
> 


More information about the CRIU mailing list