diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index e58fcac54dd8..be25d3d28074 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -1467,29 +1467,13 @@ void switch_to_sld(unsigned long tifn) } /* - * 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. + * CPU models that are known to have the per-core split-lock detection + * feature even though they do not enumerate IA32_CORE_CAPABILITIES. */ static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = { - {X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_X, X86_FEATURE_ANY, 0}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_L, X86_FEATURE_ANY, 0}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_D, X86_FEATURE_ANY, 0}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT, X86_FEATURE_ANY, 1}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_D, X86_FEATURE_ANY, 1}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_L, X86_FEATURE_ANY, 1}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY, 1}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE, X86_FEATURE_ANY, 1}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_SAPPHIRERAPIDS_X, X86_FEATURE_ANY, 1}, - {X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY, 1}, + {X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_X, X86_FEATURE_ANY, 0}, + {X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_L, X86_FEATURE_ANY, 0}, + {X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_D, X86_FEATURE_ANY, 0}, {} }; @@ -1501,24 +1485,27 @@ static void __init split_lock_setup(struct cpuinfo_x86 *c) if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) return; + /* Check for CPUs that have support but do not enumerate it: */ m = x86_match_cpu(split_lock_cpu_ids); - if (!m) + if (m) + goto supported; + + if (!cpu_has(c, X86_FEATURE_CORE_CAPABILITIES)) return; - 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); - if (!(ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT)) - return; - break; - default: - return; - } + /* + * Not all bits in MSR_IA32_CORE_CAPS are architectural, but + * MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT is. All CPUs that set + * it have split lock detection. + */ + rdmsrl(MSR_IA32_CORE_CAPS, ia32_core_caps); + if (ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT) + goto supported; + /* CPU is not in the model list and does not have the MSR bit: */ + return; + +supported: cpu_model_supports_sld = true; __split_lock_setup(); }