|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |