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.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
index d3dda716195..2e63efd5881 100644
--- a/include/asm-x86/i387.h
+++ b/include/asm-x86/i387.h
@@ -13,6 +13,7 @@
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>
@@ -294,6 +295,37 @@ static inline void kernel_fpu_end(void)
294 preempt_enable(); 295 preempt_enable();
295} 296}
296 297
298/*
299 * Some instructions like VIA's padlock instructions generate a spurious
300 * DNA fault but don't modify SSE registers. And these instructions
301 * get used from interrupt context aswell. To prevent these kernel instructions
302 * in interrupt context interact wrongly with other user/kernel fpu usage, we
303 * should use them only in the context of irq_ts_save/restore()
304 */
305static inline int irq_ts_save(void)
306{
307 /*
308 * If we are in process context, we are ok to take a spurious DNA fault.
309 * Otherwise, doing clts() in process context require pre-emption to
310 * be disabled or some heavy lifting like kernel_fpu_begin()
311 */
312 if (!in_interrupt())
313 return 0;
314
315 if (read_cr0() & X86_CR0_TS) {
316 clts();
317 return 1;
318 }
319
320 return 0;
321}
322
323static inline void irq_ts_restore(int TS_state)
324{
325 if (TS_state)
326 stts();
327}
328
297#ifdef CONFIG_X86_64 329#ifdef CONFIG_X86_64
298 330
299static inline void save_init_fpu(struct task_struct *tsk) 331static inline void save_init_fpu(struct task_struct *tsk)