Commit 3a390f24 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86-urgent-2024-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:

 - Fix regressions of the new x86 CPU VFM (vendor/family/model)
   enumeration/matching code

 - Fix crash kernel detection on buggy firmware with
   non-compliant ACPI MADT tables

 - Address Kconfig warning

* tag 'x86-urgent-2024-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/cpu: Fix x86_match_cpu() to match just X86_VENDOR_INTEL
  crypto: x86/aes-xts - switch to new Intel CPU model defines
  x86/topology: Handle bogus ACPI tables correctly
  x86/kconfig: Select ARCH_WANT_FRAME_POINTERS again when UNWINDER_FRAME_POINTER=y
parents 56676c4c 93022482
...@@ -248,6 +248,7 @@ config UNWINDER_ORC ...@@ -248,6 +248,7 @@ config UNWINDER_ORC
config UNWINDER_FRAME_POINTER config UNWINDER_FRAME_POINTER
bool "Frame pointer unwinder" bool "Frame pointer unwinder"
select ARCH_WANT_FRAME_POINTERS
select FRAME_POINTER select FRAME_POINTER
help help
This option enables the frame pointer unwinder for unwinding kernel This option enables the frame pointer unwinder for unwinding kernel
...@@ -271,7 +272,3 @@ config UNWINDER_GUESS ...@@ -271,7 +272,3 @@ config UNWINDER_GUESS
overhead. overhead.
endchoice endchoice
config FRAME_POINTER
depends on !UNWINDER_ORC && !UNWINDER_GUESS
bool
...@@ -1223,14 +1223,14 @@ DEFINE_XTS_ALG(vaes_avx10_512, "xts-aes-vaes-avx10_512", 800); ...@@ -1223,14 +1223,14 @@ DEFINE_XTS_ALG(vaes_avx10_512, "xts-aes-vaes-avx10_512", 800);
* implementation with ymm registers (256-bit vectors) will be used instead. * implementation with ymm registers (256-bit vectors) will be used instead.
*/ */
static const struct x86_cpu_id zmm_exclusion_list[] = { static const struct x86_cpu_id zmm_exclusion_list[] = {
{ .vendor = X86_VENDOR_INTEL, .family = 6, .model = INTEL_FAM6_SKYLAKE_X }, X86_MATCH_VFM(INTEL_SKYLAKE_X, 0),
{ .vendor = X86_VENDOR_INTEL, .family = 6, .model = INTEL_FAM6_ICELAKE_X }, X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
{ .vendor = X86_VENDOR_INTEL, .family = 6, .model = INTEL_FAM6_ICELAKE_D }, X86_MATCH_VFM(INTEL_ICELAKE_D, 0),
{ .vendor = X86_VENDOR_INTEL, .family = 6, .model = INTEL_FAM6_ICELAKE }, X86_MATCH_VFM(INTEL_ICELAKE, 0),
{ .vendor = X86_VENDOR_INTEL, .family = 6, .model = INTEL_FAM6_ICELAKE_L }, X86_MATCH_VFM(INTEL_ICELAKE_L, 0),
{ .vendor = X86_VENDOR_INTEL, .family = 6, .model = INTEL_FAM6_ICELAKE_NNPI }, X86_MATCH_VFM(INTEL_ICELAKE_NNPI, 0),
{ .vendor = X86_VENDOR_INTEL, .family = 6, .model = INTEL_FAM6_TIGERLAKE_L }, X86_MATCH_VFM(INTEL_TIGERLAKE_L, 0),
{ .vendor = X86_VENDOR_INTEL, .family = 6, .model = INTEL_FAM6_TIGERLAKE }, X86_MATCH_VFM(INTEL_TIGERLAKE, 0),
/* Allow Rocket Lake and later, and Sapphire Rapids and later. */ /* Allow Rocket Lake and later, and Sapphire Rapids and later. */
/* Also allow AMD CPUs (starting with Zen 4, the first with AVX-512). */ /* Also allow AMD CPUs (starting with Zen 4, the first with AVX-512). */
{}, {},
......
...@@ -53,6 +53,9 @@ ...@@ -53,6 +53,9 @@
#define X86_CENTAUR_FAM6_C7_D 0xd #define X86_CENTAUR_FAM6_C7_D 0xd
#define X86_CENTAUR_FAM6_NANO 0xf #define X86_CENTAUR_FAM6_NANO 0xf
/* x86_cpu_id::flags */
#define X86_CPU_ID_FLAG_ENTRY_VALID BIT(0)
#define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins) #define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins)
/** /**
* X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching
...@@ -79,6 +82,7 @@ ...@@ -79,6 +82,7 @@
.model = _model, \ .model = _model, \
.steppings = _steppings, \ .steppings = _steppings, \
.feature = _feature, \ .feature = _feature, \
.flags = X86_CPU_ID_FLAG_ENTRY_VALID, \
.driver_data = (unsigned long) _data \ .driver_data = (unsigned long) _data \
} }
...@@ -89,6 +93,7 @@ ...@@ -89,6 +93,7 @@
.model = _model, \ .model = _model, \
.steppings = _steppings, \ .steppings = _steppings, \
.feature = _feature, \ .feature = _feature, \
.flags = X86_CPU_ID_FLAG_ENTRY_VALID, \
.driver_data = (unsigned long) _data \ .driver_data = (unsigned long) _data \
} }
......
...@@ -38,9 +38,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) ...@@ -38,9 +38,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
const struct x86_cpu_id *m; const struct x86_cpu_id *m;
struct cpuinfo_x86 *c = &boot_cpu_data; struct cpuinfo_x86 *c = &boot_cpu_data;
for (m = match; for (m = match; m->flags & X86_CPU_ID_FLAG_ENTRY_VALID; m++) {
m->vendor | m->family | m->model | m->steppings | m->feature;
m++) {
if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor) if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
continue; continue;
if (m->family != X86_FAMILY_ANY && c->x86 != m->family) if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
......
...@@ -128,6 +128,9 @@ static void topo_set_cpuids(unsigned int cpu, u32 apic_id, u32 acpi_id) ...@@ -128,6 +128,9 @@ static void topo_set_cpuids(unsigned int cpu, u32 apic_id, u32 acpi_id)
static __init bool check_for_real_bsp(u32 apic_id) static __init bool check_for_real_bsp(u32 apic_id)
{ {
bool is_bsp = false, has_apic_base = boot_cpu_data.x86 >= 6;
u64 msr;
/* /*
* There is no real good way to detect whether this a kdump() * There is no real good way to detect whether this a kdump()
* kernel, but except on the Voyager SMP monstrosity which is not * kernel, but except on the Voyager SMP monstrosity which is not
...@@ -144,17 +147,61 @@ static __init bool check_for_real_bsp(u32 apic_id) ...@@ -144,17 +147,61 @@ static __init bool check_for_real_bsp(u32 apic_id)
if (topo_info.real_bsp_apic_id != BAD_APICID) if (topo_info.real_bsp_apic_id != BAD_APICID)
return false; return false;
/*
* Check whether the enumeration order is broken by evaluating the
* BSP bit in the APICBASE MSR. If the CPU does not have the
* APICBASE MSR then the BSP detection is not possible and the
* kernel must rely on the firmware enumeration order.
*/
if (has_apic_base) {
rdmsrl(MSR_IA32_APICBASE, msr);
is_bsp = !!(msr & MSR_IA32_APICBASE_BSP);
}
if (apic_id == topo_info.boot_cpu_apic_id) { if (apic_id == topo_info.boot_cpu_apic_id) {
/*
* If the boot CPU has the APIC BSP bit set then the
* firmware enumeration is agreeing. If the CPU does not
* have the APICBASE MSR then the only choice is to trust
* the enumeration order.
*/
if (is_bsp || !has_apic_base) {
topo_info.real_bsp_apic_id = apic_id; topo_info.real_bsp_apic_id = apic_id;
return false; return false;
} }
/*
* If the boot APIC is enumerated first, but the APICBASE
* MSR does not have the BSP bit set, then there is no way
* to discover the real BSP here. Assume a crash kernel and
* limit the number of CPUs to 1 as an INIT to the real BSP
* would reset the machine.
*/
pr_warn("Enumerated BSP APIC %x is not marked in APICBASE MSR\n", apic_id);
pr_warn("Assuming crash kernel. Limiting to one CPU to prevent machine INIT\n");
set_nr_cpu_ids(1);
goto fwbug;
}
pr_warn("Boot CPU APIC ID not the first enumerated APIC ID: %x > %x\n", pr_warn("Boot CPU APIC ID not the first enumerated APIC ID: %x != %x\n",
topo_info.boot_cpu_apic_id, apic_id); topo_info.boot_cpu_apic_id, apic_id);
if (is_bsp) {
/*
* The boot CPU has the APIC BSP bit set. Use it and complain
* about the broken firmware enumeration.
*/
topo_info.real_bsp_apic_id = topo_info.boot_cpu_apic_id;
goto fwbug;
}
pr_warn("Crash kernel detected. Disabling real BSP to prevent machine INIT\n"); pr_warn("Crash kernel detected. Disabling real BSP to prevent machine INIT\n");
topo_info.real_bsp_apic_id = apic_id; topo_info.real_bsp_apic_id = apic_id;
return true; return true;
fwbug:
pr_warn(FW_BUG "APIC enumeration order not specification compliant\n");
return false;
} }
static unsigned int topo_unit_count(u32 lvlid, enum x86_topology_domains at_level, static unsigned int topo_unit_count(u32 lvlid, enum x86_topology_domains at_level,
......
...@@ -690,6 +690,8 @@ struct x86_cpu_id { ...@@ -690,6 +690,8 @@ struct x86_cpu_id {
__u16 model; __u16 model;
__u16 steppings; __u16 steppings;
__u16 feature; /* bit index */ __u16 feature; /* bit index */
/* Solely for kernel-internal use: DO NOT EXPORT to userspace! */
__u16 flags;
kernel_ulong_t driver_data; kernel_ulong_t driver_data;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment