]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-x86/i387.h
Merge branches 'x86/prototypes', 'x86/x2apic' and 'x86/debug' into x86/core
[linux-2.6-omap-h63xx.git] / include / asm-x86 / i387.h
index 96fa8449ff11de8dcf4926f3ac541286597168d3..1ecdc3ed96e4ecf156c83cae583ad2779d96f8b9 100644 (file)
@@ -7,12 +7,13 @@
  * x86-64 work by Andi Kleen 2002
  */
 
-#ifndef _ASM_X86_I387_H
-#define _ASM_X86_I387_H
+#ifndef ASM_X86__I387_H
+#define ASM_X86__I387_H
 
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/regset.h>
+#include <linux/hardirq.h>
 #include <asm/asm.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
@@ -24,6 +25,7 @@ extern void mxcsr_feature_mask_init(void);
 extern int init_fpu(struct task_struct *child);
 extern asmlinkage void math_state_restore(void);
 extern void init_thread_xstate(void);
+extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
 
 extern user_regset_active_fn fpregs_active, xfpregs_active;
 extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get;
@@ -62,8 +64,6 @@ static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
 #else
                     : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0));
 #endif
-       if (unlikely(err))
-               init_fpu(current);
        return err;
 }
 
@@ -236,6 +236,37 @@ static inline void kernel_fpu_end(void)
        preempt_enable();
 }
 
+/*
+ * Some instructions like VIA's padlock instructions generate a spurious
+ * DNA fault but don't modify SSE registers. And these instructions
+ * get used from interrupt context aswell. To prevent these kernel instructions
+ * in interrupt context interact wrongly with other user/kernel fpu usage, we
+ * should use them only in the context of irq_ts_save/restore()
+ */
+static inline int irq_ts_save(void)
+{
+       /*
+        * If we are in process context, we are ok to take a spurious DNA fault.
+        * Otherwise, doing clts() in process context require pre-emption to
+        * be disabled or some heavy lifting like kernel_fpu_begin()
+        */
+       if (!in_interrupt())
+               return 0;
+
+       if (read_cr0() & X86_CR0_TS) {
+               clts();
+               return 1;
+       }
+
+       return 0;
+}
+
+static inline void irq_ts_restore(int TS_state)
+{
+       if (TS_state)
+               stts();
+}
+
 #ifdef CONFIG_X86_64
 
 static inline void save_init_fpu(struct task_struct *tsk)
@@ -306,4 +337,4 @@ static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk)
        }
 }
 
-#endif /* _ASM_X86_I387_H */
+#endif /* ASM_X86__I387_H */