aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 19:25:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 19:25:13 -0400
commit4a386c3e177ca2fbc70c9283d0b46537844763a0 (patch)
tree7f3a6a6a984a988e8a6e908d93dcd57d92a82efd /arch/x86/include/asm
parente8779776afbd5f2d5315cf48c4257ca7e9b250fb (diff)
parent1cff92d8fdb27684308864d9cdb324bee43b40ab (diff)
Merge branch 'x86-xsave-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-xsave-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, xsave: Make xstate_enable_boot_cpu() __init, protect on CPU 0 x86, xsave: Add __init attribute to setup_xstate_features() x86, xsave: Make init_xstate_buf static x86, xsave: Check cpuid level for XSTATE_CPUID (0x0d) x86, xsave: Introduce xstate enable functions x86, xsave: Separate fpu and xsave initialization x86, xsave: Move boot cpu initialization to xsave_init() x86, xsave: 32/64 bit boot cpu check unification in initialization x86, xsave: Do not include asm/i387.h in asm/xsave.h x86, xsave: Use xsaveopt in context-switch path when supported x86, xsave: Sync xsave memory layout with its header for user handling x86, xsave: Track the offset, size of state in the xsave layout
Diffstat (limited to 'arch/x86/include/asm')
-rw-r--r--arch/x86/include/asm/i387.h15
-rw-r--r--arch/x86/include/asm/xsave.h24
2 files changed, 32 insertions, 7 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index f1accc625beb..a73a8d5a5e69 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -31,7 +31,6 @@ extern void mxcsr_feature_mask_init(void);
31extern int init_fpu(struct task_struct *child); 31extern int init_fpu(struct task_struct *child);
32extern asmlinkage void math_state_restore(void); 32extern asmlinkage void math_state_restore(void);
33extern void __math_state_restore(void); 33extern void __math_state_restore(void);
34extern void init_thread_xstate(void);
35extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); 34extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
36 35
37extern user_regset_active_fn fpregs_active, xfpregs_active; 36extern user_regset_active_fn fpregs_active, xfpregs_active;
@@ -58,11 +57,25 @@ extern int restore_i387_xstate_ia32(void __user *buf);
58 57
59#define X87_FSW_ES (1 << 7) /* Exception Summary */ 58#define X87_FSW_ES (1 << 7) /* Exception Summary */
60 59
60static __always_inline __pure bool use_xsaveopt(void)
61{
62 return static_cpu_has(X86_FEATURE_XSAVEOPT);
63}
64
61static __always_inline __pure bool use_xsave(void) 65static __always_inline __pure bool use_xsave(void)
62{ 66{
63 return static_cpu_has(X86_FEATURE_XSAVE); 67 return static_cpu_has(X86_FEATURE_XSAVE);
64} 68}
65 69
70extern void __sanitize_i387_state(struct task_struct *);
71
72static inline void sanitize_i387_state(struct task_struct *tsk)
73{
74 if (!use_xsaveopt())
75 return;
76 __sanitize_i387_state(tsk);
77}
78
66#ifdef CONFIG_X86_64 79#ifdef CONFIG_X86_64
67 80
68/* Ignore delayed exceptions from user space */ 81/* Ignore delayed exceptions from user space */
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
index 06acdbd7570a..c6ce2452f10c 100644
--- a/arch/x86/include/asm/xsave.h
+++ b/arch/x86/include/asm/xsave.h
@@ -3,7 +3,8 @@
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <asm/processor.h> 5#include <asm/processor.h>
6#include <asm/i387.h> 6
7#define XSTATE_CPUID 0x0000000d
7 8
8#define XSTATE_FP 0x1 9#define XSTATE_FP 0x1
9#define XSTATE_SSE 0x2 10#define XSTATE_SSE 0x2
@@ -32,10 +33,8 @@
32 33
33extern unsigned int xstate_size; 34extern unsigned int xstate_size;
34extern u64 pcntxt_mask; 35extern u64 pcntxt_mask;
35extern struct xsave_struct *init_xstate_buf;
36extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; 36extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
37 37
38extern void xsave_cntxt_init(void);
39extern void xsave_init(void); 38extern void xsave_init(void);
40extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); 39extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
41extern int init_fpu(struct task_struct *child); 40extern int init_fpu(struct task_struct *child);
@@ -127,12 +126,25 @@ static inline void xrstor_state(struct xsave_struct *fx, u64 mask)
127 : "memory"); 126 : "memory");
128} 127}
129 128
129static inline void xsave_state(struct xsave_struct *fx, u64 mask)
130{
131 u32 lmask = mask;
132 u32 hmask = mask >> 32;
133
134 asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x27\n\t"
135 : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask)
136 : "memory");
137}
138
130static inline void fpu_xsave(struct fpu *fpu) 139static inline void fpu_xsave(struct fpu *fpu)
131{ 140{
132 /* This, however, we can work around by forcing the compiler to select 141 /* This, however, we can work around by forcing the compiler to select
133 an addressing mode that doesn't require extended registers. */ 142 an addressing mode that doesn't require extended registers. */
134 __asm__ __volatile__(".byte " REX_PREFIX "0x0f,0xae,0x27" 143 alternative_input(
135 : : "D" (&(fpu->state->xsave)), 144 ".byte " REX_PREFIX "0x0f,0xae,0x27",
136 "a" (-1), "d"(-1) : "memory"); 145 ".byte " REX_PREFIX "0x0f,0xae,0x37",
146 X86_FEATURE_XSAVEOPT,
147 [fx] "D" (&fpu->state->xsave), "a" (-1), "d" (-1) :
148 "memory");
137} 149}
138#endif 150#endif