[PATCH v4 2/2] ARM: vfp: clear fpscr length and stride bits on entry to sig handler

Jon Medhurst (Tixy) tixy at linaro.org
Mon May 14 13:50:44 EDT 2012


On Mon, 2012-05-14 at 18:37 +0100, Will Deacon wrote:
> You're right, in the lazy case (i.e. SMP) we update the hwstate on
> context-switch rather than on the fault. Your quick fix looks good to me
> (that is, unconditionally flushing the state after handling a signal). I was
> initially worried that the added flushing would cause a performance hit on
> the usual path, where VFP is not used in the handler, however since we flush
> before the signal handler, it really won't make a lot of difference.
> 
> I took the liberty of writing a commit message, so can I add your S-o-B to
> this please (I wasn't sure which email address to use)?

Thanks, it's the day job, so...

Signed-off-by: Jon Medhurst <tixy at linaro.org>

> Thanks,
> 
> Will
> 
> Subject: [PATCH] ARM: vfp: fix VFP flushing regression on sigreturn path
> 
> Commit ff9a184c ("ARM: 7400/1: vfp: clear fpscr length and stride bits
> on entry to sig handler") flushes the VFP state prior to entering a
> signal handler so that a VFP operation inside the handler will trap and
> force a restore of ABI-compliant registers. Restoring the registers on
> the sigreturn path is predicated on the saved thread state indicating
> that VFP was used by the handler -- however for SMP platforms this is
> only set on context-switch, making the check unreliable and causing VFP
> register corruption in userspace.
> 
> This patch unconditionally flushes the VFP state after a signal handler.
> Since we already perform the flush before the handler and the flushing
> itself happens lazily, the effect on performance is negligible.
> 
> Reported-by: Jon Medhurst <tixy at yxit.co.uk>
> Signed-off-by: Will Deacon <will.deacon at arm.com>
> ---
>  arch/arm/vfp/vfpmodule.c |   14 ++------------
>  1 files changed, 2 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
> index c5767b5..b0197b2 100644
> --- a/arch/arm/vfp/vfpmodule.c
> +++ b/arch/arm/vfp/vfpmodule.c
> @@ -577,12 +577,6 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
>  	 * entry.
>  	 */
>  	hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK);
> -
> -	/*
> -	 * Disable VFP in the hwstate so that we can detect if it gets
> -	 * used.
> -	 */
> -	hwstate->fpexc &= ~FPEXC_EN;
>  	return 0;
>  }
>  
> @@ -595,12 +589,8 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
>  	unsigned long fpexc;
>  	int err = 0;
>  
> -	/*
> -	 * If VFP has been used, then disable it to avoid corrupting
> -	 * the new thread state.
> -	 */
> -	if (hwstate->fpexc & FPEXC_EN)
> -		vfp_flush_hwstate(thread);
> +	/* Disable VFP to avoid corrupting the new thread state. */
> +	vfp_flush_hwstate(thread);
>  
>  	/*
>  	 * Copy the floating point registers. There can be unused





More information about the linux-arm-kernel mailing list