]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-x86/i387.h
Merge branch 'x86/header-guards' into x86-v28-for-linus-phase1
[linux-2.6-omap-h63xx.git] / include / asm-x86 / i387.h
index 6f60a6b8997314cf5e223f04fc2c387f9617c041..72c3bd27e8e1999097a51169c76728dbff678abf 100644 (file)
@@ -13,6 +13,7 @@
 #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>
@@ -62,8 +63,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 +235,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)