[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4/6] x86/AMD: Introduce and use X86_BUG_NULL_SEG
AMD processors don't clear the base or limit fields when loading a NULL segment, and Hygon processors inherit this behaviour. Express the logic in terms of cpu_bug_null_seg, and rearrange preload_segment() have the more predictable condition first, not reference AMD specifically. Tweak the inline ASM, as `mov %sreg` can be encoded with a memory operand. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> CC: Pu Wen <puwen@xxxxxxxx> --- xen/arch/x86/cpu/amd.c | 6 ++++++ xen/arch/x86/domain.c | 18 +++++++++--------- xen/include/asm-x86/cpufeature.h | 1 + xen/include/asm-x86/cpufeatures.h | 1 + 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c index 8089fb9..21c82bb 100644 --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -707,6 +707,12 @@ static void init_amd(struct cpuinfo_x86 *c) __clear_bit(X86_FEATURE_PBE, c->x86_capability); /* + * AMD CPUs don't zero a segments base and limit when loading a NULL + * selector. + */ + setup_force_cpu_cap(X86_BUG_NULL_SEG); + + /* * Attempt to set lfence to be Dispatch Serialising. This MSR almost * certainly isn't virtualised (and Xen at least will leak the real * value in but silently discard writes), as well as being per-core diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index beeb1d7..725d0a1 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1307,16 +1307,16 @@ arch_do_vcpu_op( } /* - * Loading a nul selector does not clear bases and limits on AMD CPUs. Be on - * the safe side and re-initialize both to flat segment values before loading - * a nul selector. + * Loading a NULL selector doesn't always clear bases and limits. Be on the + * safe side and re-initialize both to flat segment values before loading a + * NULL selector. */ -#define preload_segment(seg, value) do { \ - if ( !((value) & ~3) && \ - boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) \ - asm volatile ( "movl %k0, %%" #seg \ - :: "r" (FLAT_USER_DS32) ); \ -} while ( false ) +#define preload_segment(seg, value) \ + do { \ + if ( cpu_bug_null_seg && !((value) & ~3) ) \ + asm volatile ( "mov %k0, %%" #seg \ + :: "rm" (FLAT_USER_DS32) ); \ + } while ( 0 ) #define loadsegment(seg,value) ({ \ int __r = 1; \ diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h index 4ed7be3..de45b6c 100644 --- a/xen/include/asm-x86/cpufeature.h +++ b/xen/include/asm-x86/cpufeature.h @@ -124,6 +124,7 @@ /* Bugs. */ #define cpu_bug_amd_erratum_121 boot_cpu_has(X86_BUG_AMD_ERRATUM_121) +#define cpu_bug_null_seg boot_cpu_has(X86_BUG_NULL_SEG) enum _cache_type { CACHE_TYPE_NULL = 0, diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h index a19116c..8a73a09 100644 --- a/xen/include/asm-x86/cpufeatures.h +++ b/xen/include/asm-x86/cpufeatures.h @@ -39,6 +39,7 @@ XEN_CPUFEATURE(XEN_LBR, X86_SYNTH(22)) /* Xen uses MSR_DEBUGCTL.LBR */ #define X86_BUG(x) ((FSCAPINTS + X86_NR_SYNTH) * 32 + (x)) #define X86_BUG_AMD_ERRATUM_121 X86_BUG( 0) /* Hang on fetch across non-canonical boundary. */ +#define X86_BUG_NULL_SEG X86_BUG( 1) /* NULL-ing a selector preserves the base and limit. */ /* Total number of capability words, inc synth and bug words. */ #define NCAPINTS (FSCAPINTS + X86_NR_SYNTH + X86_NR_BUG) /* N 32-bit words worth of info */ -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |