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