]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
x86/cpu/amd: Add Spectral Chicken
authorPeter Zijlstra <peterz@infradead.org>
Tue, 14 Jun 2022 21:16:04 +0000 (23:16 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Jul 2022 09:26:45 +0000 (11:26 +0200)
commit d7caac991feeef1b871ee6988fd2c9725df09039 upstream.

Zen2 uarchs have an undocumented, unnamed, MSR that contains a chicken
bit for some speculation behaviour. It needs setting.

Note: very belatedly AMD released naming; it's now officially called
      MSR_AMD64_DE_CFG2 and MSR_AMD64_DE_CFG2_SUPPRESS_NOBR_PRED_BIT
      but shall remain the SPECTRAL CHICKEN.

Suggested-by: Andrew Cooper <Andrew.Cooper3@citrix.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/msr-index.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/cpu.h
arch/x86/kernel/cpu/hygon.c

index 77a55777e002ba5efc457de8fe2944191fd438dc..19cc68aea58aae85a538046033ee976c9c08aa5f 100644 (file)
 /* Fam 17h MSRs */
 #define MSR_F17H_IRPERF                        0xc00000e9
 
+#define MSR_ZEN2_SPECTRAL_CHICKEN      0xc00110e3
+#define MSR_ZEN2_SPECTRAL_CHICKEN_BIT  BIT_ULL(1)
+
 /* Fam 16h MSRs */
 #define MSR_F16H_L2I_PERF_CTL          0xc0010230
 #define MSR_F16H_L2I_PERF_CTR          0xc0010231
index acea05eed27d4f35a6762dbf6cd15f4202aeffad..f1f52e67e361c8896727438a96ce2026f45282ed 100644 (file)
@@ -914,6 +914,26 @@ static void init_amd_bd(struct cpuinfo_x86 *c)
        clear_rdrand_cpuid_bit(c);
 }
 
+void init_spectral_chicken(struct cpuinfo_x86 *c)
+{
+       u64 value;
+
+       /*
+        * On Zen2 we offer this chicken (bit) on the altar of Speculation.
+        *
+        * This suppresses speculation from the middle of a basic block, i.e. it
+        * suppresses non-branch predictions.
+        *
+        * We use STIBP as a heuristic to filter out Zen2 from the rest of F17H
+        */
+       if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && cpu_has(c, X86_FEATURE_AMD_STIBP)) {
+               if (!rdmsrl_safe(MSR_ZEN2_SPECTRAL_CHICKEN, &value)) {
+                       value |= MSR_ZEN2_SPECTRAL_CHICKEN_BIT;
+                       wrmsrl_safe(MSR_ZEN2_SPECTRAL_CHICKEN, value);
+               }
+       }
+}
+
 static void init_amd_zn(struct cpuinfo_x86 *c)
 {
        set_cpu_cap(c, X86_FEATURE_ZEN);
@@ -959,7 +979,8 @@ static void init_amd(struct cpuinfo_x86 *c)
        case 0x12: init_amd_ln(c); break;
        case 0x15: init_amd_bd(c); break;
        case 0x16: init_amd_jg(c); break;
-       case 0x17: fallthrough;
+       case 0x17: init_spectral_chicken(c);
+                  fallthrough;
        case 0x19: init_amd_zn(c); break;
        }
 
index 093f5fc860e3fafa864c9d1414867105402c9461..91df90abc1d9c51f28ae991ac236584da3eef29a 100644 (file)
@@ -60,6 +60,8 @@ extern void tsx_disable(void);
 static inline void tsx_init(void) { }
 #endif /* CONFIG_CPU_SUP_INTEL */
 
+extern void init_spectral_chicken(struct cpuinfo_x86 *c);
+
 extern void get_cpu_cap(struct cpuinfo_x86 *c);
 extern void get_cpu_address_sizes(struct cpuinfo_x86 *c);
 extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
index b78c471ec344b282ef81fc35728d77163fe89b6a..774ca6bfda9f4c463d4368f0ba8063cab05c4193 100644 (file)
@@ -318,6 +318,12 @@ static void init_hygon(struct cpuinfo_x86 *c)
        /* get apicid instead of initial apic id from cpuid */
        c->apicid = hard_smp_processor_id();
 
+       /*
+        * XXX someone from Hygon needs to confirm this DTRT
+        *
+       init_spectral_chicken(c);
+        */
+
        set_cpu_cap(c, X86_FEATURE_ZEN);
        set_cpu_cap(c, X86_FEATURE_CPB);