aboutsummaryrefslogtreecommitdiff
path: root/include/asm-x86/i387.h
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-08-15 13:57:32 +0200
committerIngo Molnar <mingo@elte.hu>2008-08-15 13:57:32 +0200
commit975439fe73d1f0f7ce8c235c66783bd34dc459c3 (patch)
tree84e29852d96283b13c6e603f86bd506a631343c5 /include/asm-x86/i387.h
parentef31023743e66de7184e9aad432291c842a6384b (diff)
parent129d6aba444d1e99d4cbfb9866a4652912426b65 (diff)
Merge branch 'x86/amd-iommu' into x86/urgent
Diffstat (limited to 'include/asm-x86/i387.h')
-rw-r--r--include/asm-x86/i387.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
index 0048fb77afc..56d00e31aec 100644
--- a/include/asm-x86/i387.h
+++ b/include/asm-x86/i387.h
@@ -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>
@@ -234,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)