Commit d7caac99 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Borislav Petkov
Browse files

x86/cpu/amd: Add Spectral Chicken



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: default avatarAndrew Cooper <Andrew.Cooper3@citrix.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarJosh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
parent a09a6e23
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -568,6 +568,9 @@
/* 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
+22 −1
Original line number Diff line number Diff line
@@ -862,6 +862,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);
@@ -907,7 +927,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;
	}

+2 −0
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ static inline void tsx_init(void) { }
static inline void tsx_ap_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);
+6 −0
Original line number Diff line number Diff line
@@ -302,6 +302,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);