]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
x86: Eliminate TS_XSAVE
authorAvi Kivity <avi@redhat.com>
Thu, 6 May 2010 08:45:45 +0000 (11:45 +0300)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 10 May 2010 17:39:33 +0000 (10:39 -0700)
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>
arch/x86/include/asm/i387.h
arch/x86/include/asm/thread_info.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/i387.c
arch/x86/kernel/xsave.c

index da2930924501547c0349570d12323b37522115e2..a301a6825c3a88db39c838a99c08fb6a928d7bf2 100644 (file)
@@ -56,6 +56,18 @@ extern int restore_i387_xstate_ia32(void __user *buf);
 
 #define X87_FSW_ES (1 << 7)    /* Exception Summary */
 
+static inline bool use_xsave(void)
+{
+       u8 has_xsave;
+
+       alternative_io("mov $0, %0",
+                      "mov $1, %0",
+                      X86_FEATURE_XSAVE,
+                      "=g"(has_xsave));
+
+       return has_xsave;
+}
+
 #ifdef CONFIG_X86_64
 
 /* Ignore delayed exceptions from user space */
@@ -99,7 +111,7 @@ static inline void clear_fpu_state(struct task_struct *tsk)
        /*
         * xsave header may indicate the init state of the FP.
         */
-       if ((task_thread_info(tsk)->status & TS_XSAVE) &&
+       if (use_xsave() &&
            !(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
                return;
 
@@ -164,7 +176,7 @@ static inline void fxsave(struct task_struct *tsk)
 
 static inline void __save_init_fpu(struct task_struct *tsk)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE)
+       if (use_xsave())
                xsave(tsk);
        else
                fxsave(tsk);
@@ -218,7 +230,7 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
  */
 static inline void __save_init_fpu(struct task_struct *tsk)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE) {
+       if (use_xsave()) {
                struct xsave_struct *xstate = &tsk->thread.xstate->xsave;
                struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
 
@@ -266,7 +278,7 @@ end:
 
 static inline int restore_fpu_checking(struct task_struct *tsk)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE)
+       if (use_xsave())
                return xrstor_checking(&tsk->thread.xstate->xsave);
        else
                return fxrstor_checking(&tsk->thread.xstate->fxsave);
index e0d28901e9691ee53fcd57edf0fa08a6cd5ce8c2..e9e341505ab3ce78a743aeb2e2e305a11e06a98e 100644 (file)
@@ -244,7 +244,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TS_POLLING             0x0004  /* true if in idle loop
                                           and not sleeping */
 #define TS_RESTORE_SIGMASK     0x0008  /* restore signal mask in do_signal() */
-#define TS_XSAVE               0x0010  /* Use xsave/xrstor */
 
 #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
 
index 4868e4a951eeec310c10d06428d60c49e2fe79b5..c1c00d0b1692d47bf45981439122b962a9b1dac0 100644 (file)
@@ -1243,10 +1243,7 @@ void __cpuinit cpu_init(void)
        /*
         * Force FPU initialization:
         */
-       if (cpu_has_xsave)
-               current_thread_info()->status = TS_XSAVE;
-       else
-               current_thread_info()->status = 0;
+       current_thread_info()->status = 0;
        clear_used_math();
        mxcsr_feature_mask_init();
 
index 54c31c285488e4d0db84826dcd697878e20fc953..14ca1dc7a7039f37cb5cb3f5cfa16186af12224f 100644 (file)
@@ -102,10 +102,7 @@ void __cpuinit fpu_init(void)
 
        mxcsr_feature_mask_init();
        /* clean state in init */
-       if (cpu_has_xsave)
-               current_thread_info()->status = TS_XSAVE;
-       else
-               current_thread_info()->status = 0;
+       current_thread_info()->status = 0;
        clear_used_math();
 }
 #endif /* CONFIG_X86_64 */
index 782c3a362ec611af114dd73144fe706c9d70fd16..c1b0a11033a2a037ae6869d5c81d2c3dc794c283 100644 (file)
@@ -99,7 +99,7 @@ int save_i387_xstate(void __user *buf)
                if (err)
                        return err;
 
-               if (task_thread_info(tsk)->status & TS_XSAVE)
+               if (use_xsave())
                        err = xsave_user(buf);
                else
                        err = fxsave_user(buf);
@@ -116,7 +116,7 @@ int save_i387_xstate(void __user *buf)
 
        clear_used_math(); /* trigger finit */
 
-       if (task_thread_info(tsk)->status & TS_XSAVE) {
+       if (use_xsave()) {
                struct _fpstate __user *fx = buf;
                struct _xstate __user *x = buf;
                u64 xstate_bv;
@@ -225,7 +225,7 @@ int restore_i387_xstate(void __user *buf)
                clts();
                task_thread_info(current)->status |= TS_USEDFPU;
        }
-       if (task_thread_info(tsk)->status & TS_XSAVE)
+       if (use_xsave())
                err = restore_user_xstate(buf);
        else
                err = fxrstor_checking((__force struct i387_fxsave_struct *)