diff options
author | Jeremy Compostella <jeremy.compostella@intel.com> | 2023-09-01 16:17:51 -0700 |
---|---|---|
committer | Subrata Banik <subratabanik@google.com> | 2023-09-12 16:08:57 +0000 |
commit | ba7a9eefcf4e571bc73d4be1141f676fc5547057 (patch) | |
tree | 15c15536bac498a1229465ef3df85e34d817b26a /src/soc/intel/common/block | |
parent | 2a6a79c70657435880be7f00e48debdd559b91b5 (diff) |
soc/intel/common: Fix invalid MADT entries creation
commit f8ac3dda02f22ebf857efb5b845db97f00598f7d ("soc/intel/common:
Order the CPUs based on their APIC IDs") sort algorithnm walks all the
`cpu_info' entries without discarding empty ones. Since `cpu_info' is
not initialized, the data that is used is undefined and it generally
results in the creation of invalid `Local x2APIC' entries in the
MADT ("APIC") ACPI table.
Depending on the X2APIC ID value the Linux kernel behavior
changes (cf. arch/x86/kernel/acpi/boot.c::acpi_register_lapic()):
1. If (int)ID >= MAX_LOCAL_APIC (32768), the Linux kernel discards the
entry with the "skipped apicid that is too big" INFO level
message.
2. If (int)ID < MAX_LOCAL_APIC (32768) (including negative) this data
is taken into account and it can lead to undesirable behavior such
as core being disabled as (cf. "native_cpu_up: bad cpu" ERROR
kernel message).
TEST=Verified the MADT does not contain any invalid entries on rex.
Change-Id: I19c7aa51f232bf48201bd6d28f108e9120a21f7e
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/77615
Reviewed-by: Bora Guvendik <bora.guvendik@intel.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Wonkyu Kim <wonkyu.kim@intel.com>
Diffstat (limited to 'src/soc/intel/common/block')
-rw-r--r-- | src/soc/intel/common/block/acpi/cpu_hybrid.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/src/soc/intel/common/block/acpi/cpu_hybrid.c b/src/soc/intel/common/block/acpi/cpu_hybrid.c index 9a7b768de6..f52b68f7e2 100644 --- a/src/soc/intel/common/block/acpi/cpu_hybrid.c +++ b/src/soc/intel/common/block/acpi/cpu_hybrid.c @@ -54,6 +54,8 @@ static void acpi_set_hybrid_cpu_apicid_order(void *unused) uint32_t i, j = 0; for (i = 0; i < ARRAY_SIZE(cpu_apic_info.apic_ids); i++) { + if (!cpu_infos[i].cpu) + continue; if (cpu_infos[i].cpu->path.apic.core_type == CPU_TYPE_PERF) cpu_apic_info.apic_ids[perf_core_cnt++] = cpu_infos[i].cpu->path.apic.apic_id; |