X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fasm-mips%2Ffpu.h;h=483685b1592e0f5d3a970db9cb352f10529e8745;hb=0b6249567b4ecf6e9d5a8efcf149f3e7cf788cc0;hp=58c561a9ec6b74b8eaf4c48d0609c44098e96538;hpb=050335db2a777ffaa859d77beb05fffe9e8c5ae9;p=firefly-linux-kernel-4.4.55.git diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h index 58c561a9ec6b..483685b1592e 100644 --- a/include/asm-mips/fpu.h +++ b/include/asm-mips/fpu.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -27,45 +28,27 @@ 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) @@ -134,9 +138,11 @@ static inline void restore_fp(struct task_struct *tsk) static inline fpureg_t *get_fpu_regs(struct task_struct *tsk) { - if (cpu_has_fpu) { - if ((tsk == current) && __is_fpu_owner()) + if (tsk == current) { + preempt_disable(); + if (is_fpu_owner()) _save_fp(current); + preempt_enable(); } return tsk->thread.fpu.fpr;