From 5791123356c7edd2942f87f5ba2786143776fe54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Sat, 16 Oct 2021 13:35:04 +0300 Subject: [PATCH] cpu/intel/hyperthreading: Use initial LAPIC IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For older CPU models where CPUID leaf 0xb is not supported, use initial LAPIC ID from CPUID instead of LAPIC register space to to detect if logical CPU is a hyperthreading sibling. The one in LAPIC space is more complex to read, and might not reflect CPU topology as it can be modified in XAPIC mode. Change-Id: I8c458824db1ea66948126622a3e0d0604e391e4b Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/58385 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/cpu/intel/common/hyperthreading.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/cpu/intel/common/hyperthreading.c b/src/cpu/intel/common/hyperthreading.c index 3297b381b3..f9170b383a 100644 --- a/src/cpu/intel/common/hyperthreading.c +++ b/src/cpu/intel/common/hyperthreading.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include #include #include @@ -18,22 +17,27 @@ bool intel_ht_supported(void) bool intel_ht_sibling(void) { struct cpuid_result result; - unsigned int core_ids, apic_ids, threads; + unsigned int core_ids, apic_ids; unsigned int max_leaf; + uint32_t initial_lapicid, threads; if (!intel_ht_supported()) return false; max_leaf = cpuid_get_max_func(); + + /* Detect from 32-bit X2APIC ID. */ if (max_leaf >= 0xb) { result = cpuid_ext(0xb, 0); - const uint32_t div = 1 << (result.eax & 0x1f); - return result.edx % div > 0; + threads = 1 << (result.eax & 0x1f); + initial_lapicid = result.edx; + return initial_lapicid % threads > 0; } - apic_ids = 1; - if (max_leaf >= 1) - apic_ids = (cpuid_ebx(1) >> 16) & 0xff; + /* Detect from 8-bit XAPIC ID. */ + result = cpuid_ext(0x1, 0); + initial_lapicid = result.ebx >> 24; + apic_ids = (result.ebx >> 16) & 0xff; if (apic_ids == 0) apic_ids = 1; @@ -44,5 +48,5 @@ bool intel_ht_sibling(void) } threads = (apic_ids / core_ids); - return !!(lapicid() & (threads - 1)); + return initial_lapicid % threads > 0; }