[xen stable-4.10] x86/amd: Try to set lfence as being Dispatch Serialising

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen stable-4.10] x86/amd: Try to set lfence as being Dispatch Serialising

patchbot
commit 0e12c2c881aa12016bb659ab1eb4c7289244b3e7
Author:     Andrew Cooper <[hidden email]>
AuthorDate: Thu Feb 8 11:07:02 2018 +0100
Commit:     Jan Beulich <[hidden email]>
CommitDate: Thu Feb 8 11:07:02 2018 +0100

    x86/amd: Try to set lfence as being Dispatch Serialising
   
    This property is required for the AMD's recommended mitigation for Branch
    Target Injection, but Xen needs to cope with being unable to detect or modify
    the MSR.
   
    This is part of XSA-254.
   
    Signed-off-by: Andrew Cooper <[hidden email]>
    Reviewed-by: Jan Beulich <[hidden email]>
    master commit: fe3ee5530a8d0d0b6a478167125d00c40f294a86
    master date: 2018-01-16 17:45:50 +0000
---
 xen/arch/x86/cpu/amd.c            | 35 ++++++++++++++++++++++++++++++++++-
 xen/include/asm-x86/cpufeature.h  |  1 +
 xen/include/asm-x86/cpufeatures.h |  1 +
 xen/include/asm-x86/msr-index.h   |  1 +
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 5f36ac7..40c0bac 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -558,8 +558,41 @@ static void init_amd(struct cpuinfo_x86 *c)
  wrmsr_amd_safe(0xc001100d, l, h & ~1);
  }
 
+ /*
+ * 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
+ * rather than per-thread, so do a full safe read/write/readback cycle
+ * in the worst case.
+ */
+ if (c->x86 == 0x0f || c->x86 == 0x11)
+ /* Always dispatch serialising on this hardare. */
+ __set_bit(X86_FEATURE_LFENCE_DISPATCH, c->x86_capability);
+ else /* Implicily "== 0x10 || >= 0x12" by being 64bit. */ {
+ if (rdmsr_safe(MSR_AMD64_DE_CFG, value))
+ /* Unable to read.  Assume the safer default. */
+ __clear_bit(X86_FEATURE_LFENCE_DISPATCH,
+    c->x86_capability);
+ else if (value & AMD64_DE_CFG_LFENCE_SERIALISE)
+ /* Already dispatch serialising. */
+ __set_bit(X86_FEATURE_LFENCE_DISPATCH,
+  c->x86_capability);
+ else if (wrmsr_safe(MSR_AMD64_DE_CFG,
+    value | AMD64_DE_CFG_LFENCE_SERIALISE) ||
+ rdmsr_safe(MSR_AMD64_DE_CFG, value) ||
+ !(value & AMD64_DE_CFG_LFENCE_SERIALISE))
+ /* Attempt to set failed.  Assume the safer default. */
+ __clear_bit(X86_FEATURE_LFENCE_DISPATCH,
+    c->x86_capability);
+ else
+ /* Successfully enabled! */
+ __set_bit(X86_FEATURE_LFENCE_DISPATCH,
+  c->x86_capability);
+ }
+
  /* MFENCE stops RDTSC speculation */
- __set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
+ if (!cpu_has_lfence_dispatch)
+ __set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
 
  switch(c->x86)
  {
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 84cc51d..adc333f 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -104,6 +104,7 @@
 #define cpu_has_arch_perfmon    boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
 #define cpu_has_cpuid_faulting  boot_cpu_has(X86_FEATURE_CPUID_FAULTING)
 #define cpu_has_aperfmperf      boot_cpu_has(X86_FEATURE_APERFMPERF)
+#define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH)
 
 enum _cache_type {
     CACHE_TYPE_NULL = 0,
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
index bc98227..58b37d6 100644
--- a/xen/include/asm-x86/cpufeatures.h
+++ b/xen/include/asm-x86/cpufeatures.h
@@ -22,3 +22,4 @@ XEN_CPUFEATURE(APERFMPERF,      (FSCAPINTS+0)*32+ 8) /* APERFMPERF */
 XEN_CPUFEATURE(MFENCE_RDTSC,    (FSCAPINTS+0)*32+ 9) /* MFENCE synchronizes RDTSC */
 XEN_CPUFEATURE(XEN_SMEP,        (FSCAPINTS+0)*32+10) /* SMEP gets used by Xen itself */
 XEN_CPUFEATURE(XEN_SMAP,        (FSCAPINTS+0)*32+11) /* SMAP gets used by Xen itself */
+XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+12) /* lfence set as Dispatch Serialising */
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index b99c623..9c8bae6 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -207,6 +207,7 @@
 #define MSR_AMD64_IC_CFG 0xc0011021
 #define MSR_AMD64_DC_CFG 0xc0011022
 #define MSR_AMD64_DE_CFG 0xc0011029
+#define AMD64_DE_CFG_LFENCE_SERIALISE (_AC(1, ULL) << 1)
 
 #define MSR_AMD64_DR0_ADDRESS_MASK 0xc0011027
 #define MSR_AMD64_DR1_ADDRESS_MASK 0xc0011019
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog