diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 05872d92fca2..bc683b8219b5 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -564,6 +564,21 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, | |||
564 | 564 | ||
565 | if (err) | 565 | if (err) |
566 | return -EFAULT; | 566 | return -EFAULT; |
567 | |||
568 | /* Ensure that VFP is disabled. */ | ||
569 | vfp_flush_hwstate(thread); | ||
570 | |||
571 | /* | ||
572 | * As per the PCS, clear the length and stride bits for function | ||
573 | * entry. | ||
574 | */ | ||
575 | hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); | ||
576 | |||
577 | /* | ||
578 | * Disable VFP in the hwstate so that we can detect if it gets | ||
579 | * used. | ||
580 | */ | ||
581 | hwstate->fpexc &= ~FPEXC_EN; | ||
567 | return 0; | 582 | return 0; |
568 | } | 583 | } |
569 | 584 | ||
@@ -576,7 +591,12 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, | |||
576 | unsigned long fpexc; | 591 | unsigned long fpexc; |
577 | int err = 0; | 592 | int err = 0; |
578 | 593 | ||
579 | vfp_flush_hwstate(thread); | 594 | /* |
595 | * If VFP has been used, then disable it to avoid corrupting | ||
596 | * the new thread state. | ||
597 | */ | ||
598 | if (hwstate->fpexc & FPEXC_EN) | ||
599 | vfp_flush_hwstate(thread); | ||
580 | 600 | ||
581 | /* | 601 | /* |
582 | * Copy the floating point registers. There can be unused | 602 | * Copy the floating point registers. There can be unused |