aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-05-06 04:45:45 -0400
committerH. Peter Anvin <hpa@zytor.com>2010-05-10 13:39:33 -0400
commitc9ad488289144ae5ef53b012e15895ef1f5e4bb6 (patch)
tree06c29cda09e204d3b0b5b3d9a2a97bda0b4e340d /arch/x86/include
parent250825008f1f94887bc039e9227a8adfb5ba366e (diff)
x86: Eliminate TS_XSAVE
The fpu code currently uses current->thread_info->status & TS_XSAVE as a way to distinguish between XSAVE capable processors and older processors. The decision is not really task specific; instead we use the task status to avoid a global memory reference - the value should be the same across all threads. Eliminate this tie-in into the task structure by using an alternative instruction keyed off the XSAVE cpu feature; this results in shorter and faster code, without introducing a global memory reference. [ hpa: in the future, this probably should use an asm jmp ] Signed-off-by: Avi Kivity <avi@redhat.com> Acked-by: Suresh Siddha <suresh.b.siddha@intel.com> LKML-Reference: <1273135546-29690-2-git-send-email-avi@redhat.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/include')
-rw-r--r--arch/x86/include/asm/i387.h20
-rw-r--r--arch/x86/include/asm/thread_info.h1
2 files changed, 16 insertions, 5 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index da2930924501..a301a6825c3a 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -56,6 +56,18 @@ extern int restore_i387_xstate_ia32(void __user *buf);
56 56
57#define X87_FSW_ES (1 << 7) /* Exception Summary */ 57#define X87_FSW_ES (1 << 7) /* Exception Summary */
58 58
59static inline bool use_xsave(void)
60{
61 u8 has_xsave;
62
63 alternative_io("mov $0, %0",
64 "mov $1, %0",
65 X86_FEATURE_XSAVE,
66 "=g"(has_xsave));
67
68 return has_xsave;
69}
70
59#ifdef CONFIG_X86_64 71#ifdef CONFIG_X86_64
60 72
61/* Ignore delayed exceptions from user space */ 73/* Ignore delayed exceptions from user space */
@@ -99,7 +111,7 @@ static inline void clear_fpu_state(struct task_struct *tsk)
99 /* 111 /*
100 * xsave header may indicate the init state of the FP. 112 * xsave header may indicate the init state of the FP.
101 */ 113 */
102 if ((task_thread_info(tsk)->status & TS_XSAVE) && 114 if (use_xsave() &&
103 !(xstate->xsave_hdr.xstate_bv & XSTATE_FP)) 115 !(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
104 return; 116 return;
105 117
@@ -164,7 +176,7 @@ static inline void fxsave(struct task_struct *tsk)
164 176
165static inline void __save_init_fpu(struct task_struct *tsk) 177static inline void __save_init_fpu(struct task_struct *tsk)
166{ 178{
167 if (task_thread_info(tsk)->status & TS_XSAVE) 179 if (use_xsave())
168 xsave(tsk); 180 xsave(tsk);
169 else 181 else
170 fxsave(tsk); 182 fxsave(tsk);
@@ -218,7 +230,7 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
218 */ 230 */
219static inline void __save_init_fpu(struct task_struct *tsk) 231static inline void __save_init_fpu(struct task_struct *tsk)
220{ 232{
221 if (task_thread_info(tsk)->status & TS_XSAVE) { 233 if (use_xsave()) {
222 struct xsave_struct *xstate = &tsk->thread.xstate->xsave; 234 struct xsave_struct *xstate = &tsk->thread.xstate->xsave;
223 struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; 235 struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
224 236
@@ -266,7 +278,7 @@ end:
266 278
267static inline int restore_fpu_checking(struct task_struct *tsk) 279static inline int restore_fpu_checking(struct task_struct *tsk)
268{ 280{
269 if (task_thread_info(tsk)->status & TS_XSAVE) 281 if (use_xsave())
270 return xrstor_checking(&tsk->thread.xstate->xsave); 282 return xrstor_checking(&tsk->thread.xstate->xsave);
271 else 283 else
272 return fxrstor_checking(&tsk->thread.xstate->fxsave); 284 return fxrstor_checking(&tsk->thread.xstate->fxsave);
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index e0d28901e969..e9e341505ab3 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -244,7 +244,6 @@ static inline struct thread_info *current_thread_info(void)
244#define TS_POLLING 0x0004 /* true if in idle loop 244#define TS_POLLING 0x0004 /* true if in idle loop
245 and not sleeping */ 245 and not sleeping */
246#define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal() */ 246#define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal() */
247#define TS_XSAVE 0x0010 /* Use xsave/xrstor */
248 247
249#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) 248#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
250 249