]> xenbits.xensource.com Git - xen.git/commitdiff
x86/spec-ctrl: Enable Zen2 chickenbit
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 15 Mar 2022 18:30:25 +0000 (18:30 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 12 Jul 2022 15:33:19 +0000 (16:33 +0100)
... as instructed in the Branch Type Confusion whitepaper.

This is part of XSA-407.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
(cherry picked from commit 9deaf2d932f08c16c6b96a1c426e4b1142c0cdbe)

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

index a2041e5138a24d65257ce5681c3b61d525b2d2b4..e9530d581b114213e03ea0c85606e92ee4e89bda 100644 (file)
@@ -590,6 +590,31 @@ void amd_init_ssbd(const struct cpuinfo_x86 *c)
                printk_once(XENLOG_ERR "No SSBD controls available\n");
 }
 
+/*
+ * On Zen2 we offer this chicken (bit) on the altar of Speculation.
+ *
+ * Refer to the AMD Branch Type Confusion whitepaper:
+ * https://XXX
+ *
+ * Setting this unnamed bit supposedly causes prediction information on
+ * non-branch instructions to be ignored.  It is to be set unilaterally in
+ * newer microcode.
+ *
+ * This chickenbit is something unrelated on Zen1, and Zen1 vs Zen2 isn't a
+ * simple model number comparison, so use STIBP as a heuristic to separate the
+ * two uarches in Fam17h(AMD)/18h(Hygon).
+ */
+void amd_init_spectral_chicken(void)
+{
+       uint64_t val, chickenbit = 1 << 1;
+
+       if (cpu_has_hypervisor || !boot_cpu_has(X86_FEATURE_AMD_STIBP))
+               return;
+
+       if (rdmsr_safe(MSR_AMD64_DE_CFG2, val) == 0 && !(val & chickenbit))
+               wrmsr_safe(MSR_AMD64_DE_CFG2, val | chickenbit);
+}
+
 static void init_amd(struct cpuinfo_x86 *c)
 {
        u32 l, h;
@@ -668,6 +693,9 @@ static void init_amd(struct cpuinfo_x86 *c)
 
        amd_init_ssbd(c);
 
+       if (c->x86 == 0x17)
+               amd_init_spectral_chicken();
+
        /* MFENCE stops RDTSC speculation */
        if (!cpu_has_lfence_dispatch)
                __set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
index 23ccd66115657ab5a07d6be135bd76ce698fe1fc..680b515b3c92cc841c8a47d49c1087bd3e7750cd 100644 (file)
@@ -20,3 +20,4 @@ extern bool detect_extended_topology(struct cpuinfo_x86 *c);
 
 void early_init_amd(struct cpuinfo_x86 *c);
 void amd_init_ssbd(const struct cpuinfo_x86 *c);
+void amd_init_spectral_chicken(void);
index b769e8ad9062c5b3d0803b85c74912575412b3c6..c500485dde3f213335fd224a60c50fc0b06df6f5 100644 (file)
@@ -61,6 +61,12 @@ static void init_hygon(struct cpuinfo_x86 *c)
 
        amd_init_ssbd(c);
 
+       /*
+        * TODO: Check heuristic safety with Hygon first
+       if (c->x86 == 0x18)
+               amd_init_spectral_chicken();
+        */
+
        /* MFENCE stops RDTSC speculation */
        if (!cpu_has_lfence_dispatch)
                __set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
index 20653bd6601e4cae3b6262194aae81d8e5daab80..7b8a9c2951aa57f2ef648148a3897b5d60dcde37 100644 (file)
 #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_DE_CFG2              0xc00110e3
 
 #define MSR_AMD64_DR0_ADDRESS_MASK     0xc0011027
 #define MSR_AMD64_DR1_ADDRESS_MASK     0xc0011019