aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86/i387.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-x86/i387.h')
-rw-r--r--include/asm-x86/i387.h40
1 files changed, 35 insertions, 5 deletions
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
index b1733601df95..1ecdc3ed96e4 100644
--- a/include/asm-x86/i387.h
+++ b/include/asm-x86/i387.h
@@ -7,12 +7,13 @@
7 * x86-64 work by Andi Kleen 2002 7 * x86-64 work by Andi Kleen 2002
8 */ 8 */
9 9
10#ifndef _ASM_X86_I387_H 10#ifndef ASM_X86__I387_H
11#define _ASM_X86_I387_H 11#define ASM_X86__I387_H
12 12
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/kernel_stat.h> 14#include <linux/kernel_stat.h>
15#include <linux/regset.h> 15#include <linux/regset.h>
16#include <linux/hardirq.h>
16#include <asm/asm.h> 17#include <asm/asm.h>
17#include <asm/processor.h> 18#include <asm/processor.h>
18#include <asm/sigcontext.h> 19#include <asm/sigcontext.h>
@@ -63,8 +64,6 @@ static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
63#else 64#else
64 : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0)); 65 : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0));
65#endif 66#endif
66 if (unlikely(err))
67 init_fpu(current);
68 return err; 67 return err;
69} 68}
70 69
@@ -237,6 +236,37 @@ static inline void kernel_fpu_end(void)
237 preempt_enable(); 236 preempt_enable();
238} 237}
239 238
239/*
240 * Some instructions like VIA's padlock instructions generate a spurious
241 * DNA fault but don't modify SSE registers. And these instructions
242 * get used from interrupt context aswell. To prevent these kernel instructions
243 * in interrupt context interact wrongly with other user/kernel fpu usage, we
244 * should use them only in the context of irq_ts_save/restore()
245 */
246static inline int irq_ts_save(void)
247{
248 /*
249 * If we are in process context, we are ok to take a spurious DNA fault.
250 * Otherwise, doing clts() in process context require pre-emption to
251 * be disabled or some heavy lifting like kernel_fpu_begin()
252 */
253 if (!in_interrupt())
254 return 0;
255
256 if (read_cr0() & X86_CR0_TS) {
257 clts();
258 return 1;
259 }
260
261 return 0;
262}
263
264static inline void irq_ts_restore(int TS_state)
265{
266 if (TS_state)
267 stts();
268}
269
240#ifdef CONFIG_X86_64 270#ifdef CONFIG_X86_64
241 271
242static inline void save_init_fpu(struct task_struct *tsk) 272static inline void save_init_fpu(struct task_struct *tsk)
@@ -307,4 +337,4 @@ static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk)
307 } 337 }
308} 338}
309 339
310#endif /* _ASM_X86_I387_H */ 340#endif /* ASM_X86__I387_H */