diff --git a/[refs] b/[refs] index bcb3e8479ae7..2192c08eb230 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2498814fcb3068f19b82b1519b4038721f61af43 +refs/heads/master: ff9a184cfb6542bef98aff1789481284e122a4b3 diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index 05872d92fca2..bc683b8219b5 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -564,6 +564,21 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, if (err) return -EFAULT; + + /* Ensure that VFP is disabled. */ + vfp_flush_hwstate(thread); + + /* + * As per the PCS, clear the length and stride bits for function + * 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; } @@ -576,7 +591,12 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, unsigned long fpexc; int err = 0; - vfp_flush_hwstate(thread); + /* + * If VFP has been used, then disable it to avoid corrupting + * the new thread state. + */ + if (hwstate->fpexc & FPEXC_EN) + vfp_flush_hwstate(thread); /* * Copy the floating point registers. There can be unused