X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-x86_64%2Fi387.h;h=e613b8b164e4524b22eaceef53d25681b8660cb6;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=229401824d1bb7cc746cbb2c14b3efb3eef879f5;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h index 229401824..e613b8b16 100644 --- a/include/asm-x86_64/i387.h +++ b/include/asm-x86_64/i387.h @@ -39,16 +39,25 @@ static inline int need_signal_i387(struct task_struct *me) * FPU lazy state save handling... */ -#define kernel_fpu_end() stts() - #define unlazy_fpu(tsk) do { \ if ((tsk)->thread_info->status & TS_USEDFPU) \ save_init_fpu(tsk); \ } while (0) +/* Ignore delayed exceptions from user space */ +static inline void tolerant_fwait(void) +{ + asm volatile("1: fwait\n" + "2:\n" + " .section __ex_table,\"a\"\n" + " .align 8\n" + " .quad 1b,2b\n" + " .previous\n"); +} + #define clear_fpu(tsk) do { \ if ((tsk)->thread_info->status & TS_USEDFPU) { \ - asm volatile("fnclex ; fwait"); \ + tolerant_fwait(); \ (tsk)->thread_info->status &= ~TS_USEDFPU; \ stts(); \ } \ @@ -116,6 +125,7 @@ static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) static inline void kernel_fpu_begin(void) { struct thread_info *me = current_thread_info(); + preempt_disable(); if (me->status & TS_USEDFPU) { asm volatile("rex64 ; fxsave %0 ; fnclex" : "=m" (me->task->thread.i387.fxsave)); @@ -125,9 +135,15 @@ static inline void kernel_fpu_begin(void) clts(); } +static inline void kernel_fpu_end(void) +{ + stts(); + preempt_enable(); +} + static inline void save_init_fpu( struct task_struct *tsk ) { - asm volatile( "fxsave %0 ; fnclex" + asm volatile( "rex64 ; fxsave %0 ; fnclex" : "=m" (tsk->thread.i387.fxsave)); tsk->thread_info->status &= ~TS_USEDFPU; stts();