Messages in this thread Patch in this message | | | From | Vitaly Kuznetsov <> | Subject | [PATCH RFC] x86/cpu: read processor's APIC id from local APIC | Date | Wed, 30 Aug 2017 13:57:38 +0200 |
| |
Initial APIC ID and APIC ID don't necessarily match when we're not in x2apic mode. Intel 64 and IA-32 Architectures Software Developer's Manual (Volume 3A: System Programming Guide, Part 1, March 2017) says:
"Section 8.4.5 Identifying Logical Processors in an MP System ... Read Initial APIC ID (If the process does not support CPUID leaf 0BH) - An APIC ID is assigned to a logical processor during power up. This is the initial APIC ID reported by CPUID.1:EBX[31:24] and may be different from the current value read from the local APIC."
Same section states that we can always get the current APIC id from APIC register (xapic) or by doing rdmsr (x2apic). In x2apic mode this is always equivalent to getting it from extended topology (CPUID leaf 0BH).
I'm trying to address an issue with Hyper-V guests with weird NUMA configurations. E.g. 2 node guest with 5 CPUs on each node get the following initial APIC ids: 0 1 2 3 4 8 9 10 11 12 firmware, however, changes their effective APIC ids to 0 1 2 3 4 5 6 7 8 9 In ACPI tables processors are described with these real ACPI ids and it seems that this complies to the specification. However, during boot these guests report ... Switched APIC routing to physical flat. ... [Firmware Bug]: CPU5: APIC id mismatch. Firmware: 5 APIC: 8 #6 [Firmware Bug]: CPU6: APIC id mismatch. Firmware: 6 APIC: 9 #7 ...
which is mesleading: APIC id for CPU5 is actually 5, not 8. And this matches MADT.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> --- RFC part: - It may happen that Hyper-V is actually breaking some spec here, I'm just failing to see which. - I'm probably opening pandora's box, I know :-) This code was there for more than a decade at least, something will probably break. --- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/cpu/topology.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c8b39870f33e..0951b4f40aa8 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1102,7 +1102,7 @@ static void identify_cpu(struct cpuinfo_x86 *c) apply_forced_caps(c); #ifdef CONFIG_X86_64 - c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); + c->apicid = read_apic_id(); #endif /* diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index cd531355e838..02b43685acb6 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -79,10 +79,6 @@ void detect_extended_topology(struct cpuinfo_x86 *c) c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, ht_mask_width) & core_select_mask; c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, core_plus_mask_width); - /* - * Reinit the apicid, now that we have extended initial_apicid. - */ - c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); c->x86_max_cores = (core_level_siblings / smp_num_siblings); -- 2.13.5
| |