mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: 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>
			
			
This commit is contained in:
		
							parent
							
								
									a09a6e2399
								
							
						
					
					
						commit
						d7caac991f
					
				
					 4 changed files with 33 additions and 1 deletions
				
			
		| 
						 | 
					@ -568,6 +568,9 @@
 | 
				
			||||||
/* Fam 17h MSRs */
 | 
					/* Fam 17h MSRs */
 | 
				
			||||||
#define MSR_F17H_IRPERF			0xc00000e9
 | 
					#define MSR_F17H_IRPERF			0xc00000e9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MSR_ZEN2_SPECTRAL_CHICKEN	0xc00110e3
 | 
				
			||||||
 | 
					#define MSR_ZEN2_SPECTRAL_CHICKEN_BIT	BIT_ULL(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Fam 16h MSRs */
 | 
					/* Fam 16h MSRs */
 | 
				
			||||||
#define MSR_F16H_L2I_PERF_CTL		0xc0010230
 | 
					#define MSR_F16H_L2I_PERF_CTL		0xc0010230
 | 
				
			||||||
#define MSR_F16H_L2I_PERF_CTR		0xc0010231
 | 
					#define MSR_F16H_L2I_PERF_CTR		0xc0010231
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -862,6 +862,26 @@ static void init_amd_bd(struct cpuinfo_x86 *c)
 | 
				
			||||||
	clear_rdrand_cpuid_bit(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)
 | 
					static void init_amd_zn(struct cpuinfo_x86 *c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	set_cpu_cap(c, X86_FEATURE_ZEN);
 | 
						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 0x12: init_amd_ln(c); break;
 | 
				
			||||||
	case 0x15: init_amd_bd(c); break;
 | 
						case 0x15: init_amd_bd(c); break;
 | 
				
			||||||
	case 0x16: init_amd_jg(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;
 | 
						case 0x19: init_amd_zn(c); break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,6 +61,8 @@ static inline void tsx_init(void) { }
 | 
				
			||||||
static inline void tsx_ap_init(void) { }
 | 
					static inline void tsx_ap_init(void) { }
 | 
				
			||||||
#endif /* CONFIG_CPU_SUP_INTEL */
 | 
					#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_cap(struct cpuinfo_x86 *c);
 | 
				
			||||||
extern void get_cpu_address_sizes(struct cpuinfo_x86 *c);
 | 
					extern void get_cpu_address_sizes(struct cpuinfo_x86 *c);
 | 
				
			||||||
extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
 | 
					extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -302,6 +302,12 @@ static void init_hygon(struct cpuinfo_x86 *c)
 | 
				
			||||||
	/* get apicid instead of initial apic id from cpuid */
 | 
						/* get apicid instead of initial apic id from cpuid */
 | 
				
			||||||
	c->apicid = hard_smp_processor_id();
 | 
						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_ZEN);
 | 
				
			||||||
	set_cpu_cap(c, X86_FEATURE_CPB);
 | 
						set_cpu_cap(c, X86_FEATURE_CPB);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue