vserver 1.9.5.x5
[linux-2.6.git] / include / asm-x86_64 / i387.h
index 10638b8..aa39cfd 100644 (file)
@@ -25,30 +25,29 @@ extern void mxcsr_feature_mask_init(void);
 extern void init_fpu(struct task_struct *child);
 extern int save_i387(struct _fpstate __user *buf);
 
-static inline int need_signal_i387(struct task_struct *me) 
-{ 
-       if (!me->used_math)
-               return 0;
-       me->used_math = 0; 
-       if (me->thread_info->status & TS_USEDFPU)
-               return 0;
-       return 1;
-} 
-
 /*
  * 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 +115,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 +125,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();
@@ -138,7 +144,7 @@ static inline void save_init_fpu( struct task_struct *tsk )
  */
 static inline int restore_i387(struct _fpstate __user *buf)
 {
-       return restore_fpu_checking((struct i387_fxsave_struct *)buf);
+       return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
 }
 
 #endif /* __ASM_X86_64_I387_H */