[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86: use alternatives for FS/GS base accesses



Eliminates a couple of branches in particular from the context switch
path.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -11,6 +11,7 @@
 
 #include <xen/lib/x86/msr.h>
 
+#include <asm/alternative.h>
 #include <asm/asm_defns.h>
 #include <asm/cpufeature.h>
 #include <asm/processor.h>
@@ -154,10 +155,15 @@ static inline unsigned long rdfsbase(voi
 {
     unsigned long base;
 
-    if ( cpu_has_fsgsbase )
-        return __rdfsbase();
-
-    rdmsrl(MSR_FS_BASE, base);
+    alternative_io("mov %[msr], %%ecx\n\t"
+                   "rdmsr\n\t"
+                   "shl $32, %%rdx\n\t"
+                   "or %%rdx, %[res]",
+                   /* rdfsbase rax */
+                   ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc0",
+                   X86_FEATURE_FSGSBASE,
+                   [res] "=&a" (base),
+                   [msr] "i" (MSR_FS_BASE) : "rcx", "rdx");
 
     return base;
 }
@@ -166,10 +172,15 @@ static inline unsigned long rdgsbase(voi
 {
     unsigned long base;
 
-    if ( cpu_has_fsgsbase )
-        return __rdgsbase();
-
-    rdmsrl(MSR_GS_BASE, base);
+    alternative_io("mov %[msr], %%ecx\n\t"
+                   "rdmsr\n\t"
+                   "shl $32, %%rdx\n\t"
+                   "or %%rdx, %[res]",
+                   /* rdgsbase rax */
+                   ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc8",
+                   X86_FEATURE_FSGSBASE,
+                   [res] "=&a" (base),
+                   [msr] "i" (MSR_GS_BASE) : "rcx", "rdx");
 
     return base;
 }
@@ -178,59 +189,58 @@ static inline unsigned long rdgsshadow(v
 {
     unsigned long base;
 
-    if ( cpu_has_fsgsbase )
-    {
-        asm volatile ( "swapgs" );
-        base = __rdgsbase();
-        asm volatile ( "swapgs" );
-    }
-    else
-        rdmsrl(MSR_SHADOW_GS_BASE, base);
+    alternative_io("mov %[msr], %%ecx\n\t"
+                   "rdmsr\n\t"
+                   "shl $32, %%rdx\n\t"
+                   "or %%rdx, %[res]",
+                   /* Wrapping RDGSBASE in a pair of SWAPGS. */
+                   "swapgs\n\t"
+                   ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc8\n\t" /* rdgsbase rax */
+                   "swapgs",
+                   X86_FEATURE_FSGSBASE,
+                   [res] "=&a" (base),
+                   [msr] "i" (MSR_SHADOW_GS_BASE) : "rcx", "rdx");
 
     return base;
 }
 
 static inline void wrfsbase(unsigned long base)
 {
-    if ( cpu_has_fsgsbase )
-#ifdef HAVE_AS_FSGSBASE
-        asm volatile ( "wrfsbase %0" :: "r" (base) );
-#else
-        asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd0" :: "a" (base) );
-#endif
-    else
-        wrmsrl(MSR_FS_BASE, base);
+    alternative_input("mov %[msr], %%ecx\n\t"
+                      "mov %[val], %%rdx\n\t"
+                      "shr $32, %%rdx\n\t"
+                      "wrmsr",
+                      /* wrfsbase rax */
+                      ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd0",
+                      X86_FEATURE_FSGSBASE,
+                      [val] "a" (base), [msr] "i" (MSR_FS_BASE) : "rcx", 
"rdx");
 }
 
 static inline void wrgsbase(unsigned long base)
 {
-    if ( cpu_has_fsgsbase )
-#ifdef HAVE_AS_FSGSBASE
-        asm volatile ( "wrgsbase %0" :: "r" (base) );
-#else
-        asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd8" :: "a" (base) );
-#endif
-    else
-        wrmsrl(MSR_GS_BASE, base);
+    alternative_input("mov %[msr], %%ecx\n\t"
+                      "mov %[val], %%rdx\n\t"
+                      "shr $32, %%rdx\n\t"
+                      "wrmsr",
+                      /* wrgsbase rax */
+                      ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd8",
+                      X86_FEATURE_FSGSBASE,
+                      [val] "a" (base), [msr] "i" (MSR_GS_BASE) : "rcx", 
"rdx");
 }
 
 static inline void wrgsshadow(unsigned long base)
 {
-    if ( cpu_has_fsgsbase )
-    {
-        asm volatile ( "swapgs\n\t"
-#ifdef HAVE_AS_FSGSBASE
-                       "wrgsbase %0\n\t"
-                       "swapgs"
-                       :: "r" (base) );
-#else
-                       ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd8\n\t"
-                       "swapgs"
-                       :: "a" (base) );
-#endif
-    }
-    else
-        wrmsrl(MSR_SHADOW_GS_BASE, base);
+    alternative_input("mov %[msr], %%ecx\n\t"
+                      "mov %[val], %%rdx\n\t"
+                      "shr $32, %%rdx\n\t"
+                      "wrmsr",
+                      /* Wrapping WRGSBASE in a pair of SWAPGS. */
+                      "swapgs\n\t"
+                      ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd8\n\t" /* wrgsbase rax 
*/
+                      "swapgs",
+                      X86_FEATURE_FSGSBASE,
+                      [val] "a" (base),
+                      [msr] "i" (MSR_SHADOW_GS_BASE) : "rcx", "rdx");
 }
 
 DECLARE_PER_CPU(uint64_t, efer);




_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.