diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 19:25:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 19:25:13 -0400 |
commit | 4a386c3e177ca2fbc70c9283d0b46537844763a0 (patch) | |
tree | 7f3a6a6a984a988e8a6e908d93dcd57d92a82efd /arch/x86/include/asm | |
parent | e8779776afbd5f2d5315cf48c4257ca7e9b250fb (diff) | |
parent | 1cff92d8fdb27684308864d9cdb324bee43b40ab (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.h | 15 | ||||
-rw-r--r-- | arch/x86/include/asm/xsave.h | 24 |
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); | |||
31 | extern int init_fpu(struct task_struct *child); | 31 | extern int init_fpu(struct task_struct *child); |
32 | extern asmlinkage void math_state_restore(void); | 32 | extern asmlinkage void math_state_restore(void); |
33 | extern void __math_state_restore(void); | 33 | extern void __math_state_restore(void); |
34 | extern void init_thread_xstate(void); | ||
35 | extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); | 34 | extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); |
36 | 35 | ||
37 | extern user_regset_active_fn fpregs_active, xfpregs_active; | 36 | extern 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 | ||
60 | static __always_inline __pure bool use_xsaveopt(void) | ||
61 | { | ||
62 | return static_cpu_has(X86_FEATURE_XSAVEOPT); | ||
63 | } | ||
64 | |||
61 | static __always_inline __pure bool use_xsave(void) | 65 | static __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 | ||
70 | extern void __sanitize_i387_state(struct task_struct *); | ||
71 | |||
72 | static 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 | ||
33 | extern unsigned int xstate_size; | 34 | extern unsigned int xstate_size; |
34 | extern u64 pcntxt_mask; | 35 | extern u64 pcntxt_mask; |
35 | extern struct xsave_struct *init_xstate_buf; | ||
36 | extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; | 36 | extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; |
37 | 37 | ||
38 | extern void xsave_cntxt_init(void); | ||
39 | extern void xsave_init(void); | 38 | extern void xsave_init(void); |
40 | extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); | 39 | extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); |
41 | extern int init_fpu(struct task_struct *child); | 40 | extern 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 | ||
129 | static 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 | |||
130 | static inline void fpu_xsave(struct fpu *fpu) | 139 | static 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 |