Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh...
[sfrench/cifs-2.6.git] / include / asm-mips / fpu.h
index efef843b93f0c1694a2084f1a502523a5ac69318..483685b1592e0f5d3a970db9cb352f10529e8745 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/mipsregs.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
+#include <asm/hazards.h>
 #include <asm/bitops.h>
 #include <asm/processor.h>
 #include <asm/current.h>
 struct sigcontext;
 struct sigcontext32;
 
-extern asmlinkage int (*save_fp_context)(struct sigcontext *sc);
-extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
+extern asmlinkage int (*save_fp_context)(struct sigcontext __user *sc);
+extern asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc);
 
-extern asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc);
-extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc);
+extern asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc);
+extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc);
 
 extern void fpu_emulator_init_fpu(void);
 extern void _init_fpu(void);
 extern void _save_fp(struct task_struct *);
 extern void _restore_fp(struct task_struct *);
 
-#if defined(CONFIG_CPU_SB1)
-#define __enable_fpu_hazard()                                          \
-do {                                                                   \
-       asm(".set       push            \n\t"                           \
-           ".set       mips64          \n\t"                           \
-           ".set       noreorder       \n\t"                           \
-           "ssnop                      \n\t"                           \
-           "bnezl      $0, .+4         \n\t"                           \
-           "ssnop                      \n\t"                           \
-           ".set pop");                                                \
-} while (0)
-#else
-#define __enable_fpu_hazard()                                          \
-do {                                                                   \
-       asm("nop;nop;nop;nop");         /* max. hazard */               \
-} while (0)
-#endif
-
 #define __enable_fpu()                                                 \
 do {                                                                   \
         set_c0_status(ST0_CU1);                                                \
-        __enable_fpu_hazard();                                         \
+        enable_fpu_hazard();                                           \
 } while (0)
 
 #define __disable_fpu()                                                        \
 do {                                                                   \
        clear_c0_status(ST0_CU1);                                       \
-       /* We don't care about the c0 hazard here  */                   \
+        disable_fpu_hazard();                                          \
 } while (0)
 
 #define enable_fpu()                                                   \
@@ -93,31 +76,52 @@ static inline int is_fpu_owner(void)
        return cpu_has_fpu && __is_fpu_owner();
 }
 
-static inline void own_fpu(void)
+static inline void __own_fpu(void)
 {
-       if (cpu_has_fpu) {
-               __enable_fpu();
-               KSTK_STATUS(current) |= ST0_CU1;
-               set_thread_flag(TIF_USEDFPU);
+       __enable_fpu();
+       KSTK_STATUS(current) |= ST0_CU1;
+       set_thread_flag(TIF_USEDFPU);
+}
+
+static inline void own_fpu_inatomic(int restore)
+{
+       if (cpu_has_fpu && !__is_fpu_owner()) {
+               __own_fpu();
+               if (restore)
+                       _restore_fp(current);
        }
 }
 
-static inline void lose_fpu(void)
+static inline void own_fpu(int restore)
 {
-       if (cpu_has_fpu) {
+       preempt_disable();
+       own_fpu_inatomic(restore);
+       preempt_enable();
+}
+
+static inline void lose_fpu(int save)
+{
+       preempt_disable();
+       if (is_fpu_owner()) {
+               if (save)
+                       _save_fp(current);
                KSTK_STATUS(current) &= ~ST0_CU1;
                clear_thread_flag(TIF_USEDFPU);
                __disable_fpu();
        }
+       preempt_enable();
 }
 
 static inline void init_fpu(void)
 {
+       preempt_disable();
        if (cpu_has_fpu) {
+               __own_fpu();
                _init_fpu();
        } else {
                fpu_emulator_init_fpu();
        }
+       preempt_enable();
 }
 
 static inline void save_fp(struct task_struct *tsk)