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.
Unified · Split
| @@ -568,6 +568,9 @@ · 567 unmodified lines | ||
| 568 | 568 | /* Fam 17h MSRs */ |
| 569 | 569 | #define MSR_F17H_IRPERF 0xc00000e9 |
| 570 | 570 | |
| 571 | +#define MSR_ZEN2_SPECTRAL_CHICKEN 0xc00110e3 | |
| 572 | +#define MSR_ZEN2_SPECTRAL_CHICKEN_BIT BIT_ULL(1) | |
| 573 | + | |
| 571 | 574 | /* Fam 16h MSRs */ |
| 572 | 575 | #define MSR_F16H_L2I_PERF_CTL 0xc0010230 |
| 573 | 576 | #define MSR_F16H_L2I_PERF_CTR 0xc0010231 |
| @@ -862,6 +862,26 @@ static void init_amd_bd(struct cpuinfo_x86 *c) · 861 unmodified lines | ||
| 862 | 862 | clear_rdrand_cpuid_bit(c); |
| 863 | 863 | } |
| 864 | 864 | |
| 865 | +void init_spectral_chicken(struct cpuinfo_x86 *c) | |
| 866 | +{ | |
| 867 | + u64 value; | |
| 868 | + | |
| 869 | + /* | |
| 870 | + * On Zen2 we offer this chicken (bit) on the altar of Speculation. | |
| 871 | + * | |
| 872 | + * This suppresses speculation from the middle of a basic block, i.e. it | |
| 873 | + * suppresses non-branch predictions. | |
| 874 | + * | |
| 875 | + * We use STIBP as a heuristic to filter out Zen2 from the rest of F17H | |
| 876 | + */ | |
| 877 | + if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && cpu_has(c, X86_FEATURE_AMD_STIBP)) { | |
| 878 | + if (!rdmsrl_safe(MSR_ZEN2_SPECTRAL_CHICKEN, &value)) { | |
| 879 | + value |= MSR_ZEN2_SPECTRAL_CHICKEN_BIT; | |
| 880 | + wrmsrl_safe(MSR_ZEN2_SPECTRAL_CHICKEN, value); | |
| 881 | + } | |
| 882 | + } | |
| 883 | +} | |
| 884 | + | |
| 865 | 885 | static void init_amd_zn(struct cpuinfo_x86 *c) |
| 866 | 886 | { |
| 867 | 887 | set_cpu_cap(c, X86_FEATURE_ZEN); |
| @@ -907,7 +927,8 @@ static void init_amd(struct cpuinfo_x86 *c) · 39 unmodified lines | ||
| 907 | 927 | case 0x12: init_amd_ln(c); break; |
| 908 | 928 | case 0x15: init_amd_bd(c); break; |
| 909 | 929 | case 0x16: init_amd_jg(c); break; |
| 910 | − case 0x17: fallthrough; | |
| 930 | + case 0x17: init_spectral_chicken(c); | |
| 931 | + fallthrough; | |
| 911 | 932 | case 0x19: init_amd_zn(c); break; |
| 912 | 933 | } |
| 913 | 934 | |
| @@ -61,6 +61,8 @@ static inline void tsx_init(void) { } · 60 unmodified lines | ||
| 61 | 61 | static inline void tsx_ap_init(void) { } |
| 62 | 62 | #endif /* CONFIG_CPU_SUP_INTEL */ |
| 63 | 63 | |
| 64 | +extern void init_spectral_chicken(struct cpuinfo_x86 *c); | |
| 65 | + | |
| 64 | 66 | extern void get_cpu_cap(struct cpuinfo_x86 *c); |
| 65 | 67 | extern void get_cpu_address_sizes(struct cpuinfo_x86 *c); |
| 66 | 68 | extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); |
| @@ -302,6 +302,12 @@ static void init_hygon(struct cpuinfo_x86 *c) · 301 unmodified lines | ||
| 302 | 302 | /* get apicid instead of initial apic id from cpuid */ |
| 303 | 303 | c->apicid = hard_smp_processor_id(); |
| 304 | 304 | |
| 305 | + /* | |
| 306 | + * XXX someone from Hygon needs to confirm this DTRT | |
| 307 | + * | |
| 308 | + init_spectral_chicken(c); | |
| 309 | + */ | |
| 310 | + | |
| 305 | 311 | set_cpu_cap(c, X86_FEATURE_ZEN); |
| 306 | 312 | set_cpu_cap(c, X86_FEATURE_CPB); |
| 307 | 313 | |