diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-09-04 12:04:45 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-09-04 12:04:45 -0400 |
commit | fe47784ba5cbb6b713c013e046859946789b45e4 (patch) | |
tree | 6384958d55e29be0d2eb8ae78fa437c10636d8d6 /include/asm-x86/i387.h | |
parent | 83b8e28b14d63db928cb39e5c5ed2a548246bd71 (diff) | |
parent | af2e1f276ff08f17192411ea3b71c13a758dfe12 (diff) |
Merge branch 'x86/cpu' into x86/xsave
Conflicts:
arch/x86/kernel/cpu/feature_names.c
include/asm-x86/cpufeature.h
Diffstat (limited to 'include/asm-x86/i387.h')
-rw-r--r-- | include/asm-x86/i387.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index d3dda7161954..2e63efd58814 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 | */ | ||
305 | static 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 | |||
323 | static 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 | ||
299 | static inline void save_init_fpu(struct task_struct *tsk) | 331 | static inline void save_init_fpu(struct task_struct *tsk) |