[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

 


Rackspace

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