summaryrefslogtreecommitdiff
path: root/arch/mips/include/asm/fpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/include/asm/fpu.h')
-rw-r--r--arch/mips/include/asm/fpu.h27
1 files changed, 17 insertions, 10 deletions
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index dd083e999b08..084780b355aa 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -30,7 +30,7 @@
struct sigcontext;
struct sigcontext32;
-extern void _init_fpu(void);
+extern void _init_fpu(unsigned int);
extern void _save_fp(struct task_struct *);
extern void _restore_fp(struct task_struct *);
@@ -48,6 +48,12 @@ enum fpu_mode {
#define FPU_FR_MASK 0x1
};
+#define __disable_fpu() \
+do { \
+ clear_c0_status(ST0_CU1); \
+ disable_fpu_hazard(); \
+} while (0)
+
static inline int __enable_fpu(enum fpu_mode mode)
{
int fr;
@@ -86,7 +92,12 @@ fr_common:
enable_fpu_hazard();
/* check FR has the desired value */
- return (!!(read_c0_status() & ST0_FR) == !!fr) ? 0 : SIGFPE;
+ if (!!(read_c0_status() & ST0_FR) == !!fr)
+ return 0;
+
+ /* unsupported FR value */
+ __disable_fpu();
+ return SIGFPE;
default:
BUG();
@@ -95,12 +106,6 @@ fr_common:
return SIGFPE;
}
-#define __disable_fpu() \
-do { \
- clear_c0_status(ST0_CU1); \
- disable_fpu_hazard(); \
-} while (0)
-
#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU)
static inline int __is_fpu_owner(void)
@@ -170,6 +175,7 @@ static inline void lose_fpu(int save)
}
disable_msa();
clear_thread_flag(TIF_USEDMSA);
+ __disable_fpu();
} else if (is_fpu_owner()) {
if (save)
_save_fp(current);
@@ -182,6 +188,7 @@ static inline void lose_fpu(int save)
static inline int init_fpu(void)
{
+ unsigned int fcr31 = current->thread.fpu.fcr31;
int ret = 0;
if (cpu_has_fpu) {
@@ -192,7 +199,7 @@ static inline int init_fpu(void)
return ret;
if (!cpu_has_fre) {
- _init_fpu();
+ _init_fpu(fcr31);
return 0;
}
@@ -206,7 +213,7 @@ static inline int init_fpu(void)
config5 = clear_c0_config5(MIPS_CONF5_FRE);
enable_fpu_hazard();
- _init_fpu();
+ _init_fpu(fcr31);
/* Restore FRE */
write_c0_config5(config5);