[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 |