ARM: 7400/1: vfp: clear fpscr length and stride bits on entry to sig handler
[linux-2.6.git] / arch / arm / vfp / vfpmodule.c
index a9c5097..dd89d31 100644 (file)
@@ -574,6 +574,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;
 }
 
@@ -586,7 +601,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