]> xenbits.xensource.com Git - xen.git/commitdiff
x86/amd: Try to set lfence as being Dispatch Serialising
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 8 Feb 2018 11:17:42 +0000 (12:17 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 8 Feb 2018 11:17:42 +0000 (12:17 +0100)
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 <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: fe3ee5530a8d0d0b6a478167125d00c40f294a86
master date: 2018-01-16 17:45:50 +0000

xen/arch/x86/cpu/amd.c
xen/include/asm-x86/cpufeature.h
xen/include/asm-x86/cpufeatures.h
xen/include/asm-x86/msr-index.h

index 5f36ac75a71124faf08c564224cd4b285c86eae0..40c0bac80b91ed6c8093ff6f8c190e5a70423a6d 100644 (file)
@@ -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)
        {
index 84cc51d2bdc80c7182647c783a8cedfb58648e0f..adc333f20ea02d2f9ef49a0634dcd2e1c89ce687 100644 (file)
 #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,
index 3fa9b0a6c8ceed31930e221001debbd2f26a8042..f26dd8704aa2d9b4d83caf473341e084ce0a1915 100644 (file)
@@ -24,3 +24,4 @@ XEN_CPUFEATURE(XEN_SMEP,        (FSCAPINTS+0)*32+10) /* SMEP gets used by Xen it
 XEN_CPUFEATURE(XEN_SMAP,        (FSCAPINTS+0)*32+11) /* SMAP gets used by Xen itself */
 XEN_CPUFEATURE(MSR_PLATFORM_INFO, (FSCAPINTS+0)*32+12) /* PLATFORM_INFO MSR present */
 XEN_CPUFEATURE(MSR_MISC_FEATURES, (FSCAPINTS+0)*32+13) /* MISC_FEATURES_ENABLES MSR present */
+XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+14) /* lfence set as Dispatch Serialising */
index 99400bd4c08fedae911bbc07c2f4ee2010f8bede..be64350040f1b36caef6aba0461e81c52f4d8dbb 100644 (file)
 #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