diff options
Diffstat (limited to 'arch/x86/kernel/cpu/intel.c')
| -rw-r--r-- | arch/x86/kernel/cpu/intel.c | 54 | 
1 files changed, 36 insertions, 18 deletions
| diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index bf08d4508ecb..a19a680542ce 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -1119,35 +1119,53 @@ void switch_to_sld(unsigned long tifn)  	sld_update_msr(!(tifn & _TIF_SLD));  } -#define SPLIT_LOCK_CPU(model) {X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY} -  /* - * The following processors have the split lock detection feature. But - * since they don't have the IA32_CORE_CAPABILITIES MSR, the feature cannot - * be enumerated. Enable it by family and model matching on these - * processors. + * Bits in the IA32_CORE_CAPABILITIES are not architectural, so they should + * only be trusted if it is confirmed that a CPU model implements a + * specific feature at a particular bit position. + * + * The possible driver data field values: + * + * - 0: CPU models that are known to have the per-core split-lock detection + *	feature even though they do not enumerate IA32_CORE_CAPABILITIES. + * + * - 1: CPU models which may enumerate IA32_CORE_CAPABILITIES and if so use + *      bit 5 to enumerate the per-core split-lock detection feature.   */  static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = { -	SPLIT_LOCK_CPU(INTEL_FAM6_ICELAKE_X), -	SPLIT_LOCK_CPU(INTEL_FAM6_ICELAKE_L), +	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X,		0), +	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L,		0), +	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT,	1), +	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D,	1), +	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L,	1),  	{}  };  void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)  { -	u64 ia32_core_caps = 0; +	const struct x86_cpu_id *m; +	u64 ia32_core_caps; + +	if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) +		return; -	if (c->x86_vendor != X86_VENDOR_INTEL) +	m = x86_match_cpu(split_lock_cpu_ids); +	if (!m)  		return; -	if (cpu_has(c, X86_FEATURE_CORE_CAPABILITIES)) { -		/* Enumerate features reported in IA32_CORE_CAPABILITIES MSR. */ + +	switch (m->driver_data) { +	case 0: +		break; +	case 1: +		if (!cpu_has(c, X86_FEATURE_CORE_CAPABILITIES)) +			return;  		rdmsrl(MSR_IA32_CORE_CAPS, ia32_core_caps); -	} else if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) { -		/* Enumerate split lock detection by family and model. */ -		if (x86_match_cpu(split_lock_cpu_ids)) -			ia32_core_caps |= MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT; +		if (!(ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT)) +			return; +		break; +	default: +		return;  	} -	if (ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT) -		split_lock_setup(); +	split_lock_setup();  } |