diff options
author | Fenghua Yu <fenghua.yu@intel.com> | 2014-05-29 14:12:37 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-05-29 17:31:25 -0400 |
commit | f9de314b340f4816671f037e79ed01f685ac9787 (patch) | |
tree | 13df1f8ba497a3bef4b272c529c942dfb593aa54 /arch | |
parent | f31a9f7c71691569359fa7fb8b0acaa44bce0324 (diff) |
x86/xsaves: Use xsaves/xrstors for context switch
If xsaves is eanbled, use xsaves/xrstors for context switch to support
compacted format xsave area to occupy less memory and modified optimization
to improve saving performance.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Link: http://lkml.kernel.org/r/1401387164-43416-10-git-send-email-fenghua.yu@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/xsave.h | 37 |
1 files changed, 12 insertions, 25 deletions
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index f9177a2a97e9..8b75824e41dd 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
@@ -129,22 +129,20 @@ static inline int xrstor_state(struct xsave_struct *fx, u64 mask) | |||
129 | return err; | 129 | return err; |
130 | } | 130 | } |
131 | 131 | ||
132 | static inline int fpu_xrstor_checking(struct xsave_struct *fx) | 132 | /* |
133 | * Save xstate context for old process during context switch. | ||
134 | */ | ||
135 | static inline void fpu_xsave(struct fpu *fpu) | ||
133 | { | 136 | { |
134 | int err; | 137 | xsave_state(&fpu->state->xsave, -1); |
135 | 138 | } | |
136 | asm volatile("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n\t" | ||
137 | "2:\n" | ||
138 | ".section .fixup,\"ax\"\n" | ||
139 | "3: movl $-1,%[err]\n" | ||
140 | " jmp 2b\n" | ||
141 | ".previous\n" | ||
142 | _ASM_EXTABLE(1b, 3b) | ||
143 | : [err] "=r" (err) | ||
144 | : "D" (fx), "m" (*fx), "a" (-1), "d" (-1), "0" (0) | ||
145 | : "memory"); | ||
146 | 139 | ||
147 | return err; | 140 | /* |
141 | * Restore xstate context for new process during context switch. | ||
142 | */ | ||
143 | static inline int fpu_xrstor_checking(struct xsave_struct *fx) | ||
144 | { | ||
145 | return xrstor_state(fx, -1); | ||
148 | } | 146 | } |
149 | 147 | ||
150 | static inline int xsave_user(struct xsave_struct __user *buf) | 148 | static inline int xsave_user(struct xsave_struct __user *buf) |
@@ -194,15 +192,4 @@ static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask) | |||
194 | return err; | 192 | return err; |
195 | } | 193 | } |
196 | 194 | ||
197 | static inline void fpu_xsave(struct fpu *fpu) | ||
198 | { | ||
199 | /* This, however, we can work around by forcing the compiler to select | ||
200 | an addressing mode that doesn't require extended registers. */ | ||
201 | alternative_input( | ||
202 | ".byte " REX_PREFIX "0x0f,0xae,0x27", | ||
203 | ".byte " REX_PREFIX "0x0f,0xae,0x37", | ||
204 | X86_FEATURE_XSAVEOPT, | ||
205 | [fx] "D" (&fpu->state->xsave), "a" (-1), "d" (-1) : | ||
206 | "memory"); | ||
207 | } | ||
208 | #endif | 195 | #endif |