x86/cpu/topology: Always try cpu_parse_topology_ext() on AMD/Hygon

Support for parsing the topology on AMD/Hygon processors using CPUID leaf 0xb
was added in

3986a0a805e6 ("x86/CPU/AMD: Derive CPU topology from CPUID function 0xB when available").

In an effort to keep all the topology parsing bits in one place, this commit
also introduced a pseudo dependency on the TOPOEXT feature to parse the CPUID
leaf 0xb.

The TOPOEXT feature (CPUID 0x80000001 ECX[22]) advertises the support for
Cache Properties leaf 0x8000001d and the CPUID leaf 0x8000001e EAX for
"Extended APIC ID" however support for 0xb was introduced alongside the x2APIC
support not only on AMD [1], but also historically on x86 [2].

Similar to 0xb, the support for extended CPU topology leaf 0x80000026 too does
not depend on the TOPOEXT feature.

The support for these leaves is expected to be confirmed by ensuring

leaf <= {extended_}cpuid_level

and then parsing the level 0 of the respective leaf to confirm EBX[15:0]
(LogProcAtThisLevel) is non-zero as stated in the definition of
"CPUID_Fn0000000B_EAX_x00 [Extended Topology Enumeration]
(Core::X86::Cpuid::ExtTopEnumEax0)" in Processor Programming Reference (PPR)
for AMD Family 19h Model 01h Rev B1 Vol1 [3] Sec. 2.1.15.1 "CPUID Instruction
Functions".

This has not been a problem on baremetal platforms since support for TOPOEXT
(Fam 0x15 and later) predates the support for CPUID leaf 0xb (Fam 0x17[Zen2]
and later), however, for AMD guests on QEMU, the "x2apic" feature can be
enabled independent of the "topoext" feature where QEMU expects topology and
the initial APICID to be parsed using the CPUID leaf 0xb (especially when
number of cores > 255) which is populated independent of the "topoext" feature
flag.

Unconditionally call cpu_parse_topology_ext() on AMD and Hygon processors to
first parse the topology using the XTOPOLOGY leaves (0x80000026 / 0xb) before
using the TOPOEXT leaf (0x8000001e).

While at it, break down the single large comment in parse_topology_amd() to
better highlight the purpose of each CPUID leaf.

Fixes: 3986a0a805e6 ("x86/CPU/AMD: Derive CPU topology from CPUID function 0xB when available")
Suggested-by: Naveen N Rao (AMD) <naveen@kernel.org>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: stable@vger.kernel.org # Only v6.9 and above; depends on x86 topology rewrite
Link: https://lore.kernel.org/lkml/1529686927-7665-1-git-send-email-suravee.suthikulpanit@amd.com/ [1]
Link: https://lore.kernel.org/lkml/20080818181435.523309000@linux-os.sc.intel.com/ [2]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537 [3]

authored by K Prateek Nayak and committed by Borislav Petkov (AMD) cba4262a 76eeb9b8

+14 -11
+14 -11
arch/x86/kernel/cpu/topology_amd.c
··· 175 175 176 176 static void parse_topology_amd(struct topo_scan *tscan) 177 177 { 178 - bool has_topoext = false; 179 - 180 178 /* 181 - * If the extended topology leaf 0x8000_001e is available 182 - * try to get SMT, CORE, TILE, and DIE shifts from extended 179 + * Try to get SMT, CORE, TILE, and DIE shifts from extended 183 180 * CPUID leaf 0x8000_0026 on supported processors first. If 184 181 * extended CPUID leaf 0x8000_0026 is not supported, try to 185 - * get SMT and CORE shift from leaf 0xb first, then try to 186 - * get the CORE shift from leaf 0x8000_0008. 182 + * get SMT and CORE shift from leaf 0xb. If either leaf is 183 + * available, cpu_parse_topology_ext() will return true. 187 184 */ 188 - if (cpu_feature_enabled(X86_FEATURE_TOPOEXT)) 189 - has_topoext = cpu_parse_topology_ext(tscan); 185 + bool has_xtopology = cpu_parse_topology_ext(tscan); 190 186 191 187 if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) 192 188 tscan->c->topo.cpu_type = cpuid_ebx(0x80000026); 193 189 194 - if (!has_topoext && !parse_8000_0008(tscan)) 190 + /* 191 + * If XTOPOLOGY leaves (0x26/0xb) are not available, try to 192 + * get the CORE shift from leaf 0x8000_0008 first. 193 + */ 194 + if (!has_xtopology && !parse_8000_0008(tscan)) 195 195 return; 196 196 197 - /* Prefer leaf 0x8000001e if available */ 198 - if (parse_8000_001e(tscan, has_topoext)) 197 + /* 198 + * Prefer leaf 0x8000001e if available to get the SMT shift and 199 + * the initial APIC ID if XTOPOLOGY leaves are not available. 200 + */ 201 + if (parse_8000_001e(tscan, has_xtopology)) 199 202 return; 200 203 201 204 /* Try the NODEID MSR */