Skip to content

Commit bda74aa

Browse files
committed
x86/cpu: Add legacy topology parser
The legacy topology detection via CPUID leaf 4, which provides the number of cores in the package and CPUID leaf 1 which provides the number of logical CPUs in case that FEATURE_HT is enabled and the CMP_LEGACY feature is not set, is shared for Intel, Centaur and Zhaoxin CPUs. Lift the code from common.c without the early detection hack and provide it as common fallback mechanism. Will be utilized in later changes. Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Juergen Gross <[email protected]> Tested-by: Sohil Mehta <[email protected]> Tested-by: Michael Kelley <[email protected]> Tested-by: Zhang Rui <[email protected]> Tested-by: Wang Wendy <[email protected]> Tested-by: K Prateek Nayak <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent ebdb203 commit bda74aa

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

arch/x86/kernel/cpu/common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,9 @@ void detect_ht(struct cpuinfo_x86 *c)
892892
#ifdef CONFIG_SMP
893893
int index_msb, core_bits;
894894

895+
if (topo_is_converted(c))
896+
return;
897+
895898
if (detect_ht_early(c) < 0)
896899
return;
897900

arch/x86/kernel/cpu/topology.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ struct topo_scan {
66
struct cpuinfo_x86 *c;
77
unsigned int dom_shifts[TOPO_MAX_DOMAIN];
88
unsigned int dom_ncpus[TOPO_MAX_DOMAIN];
9+
10+
/* Legacy CPUID[1]:EBX[23:16] number of logical processors */
11+
unsigned int ebx1_nproc_shift;
912
};
1013

1114
bool topo_is_converted(struct cpuinfo_x86 *c);

arch/x86/kernel/cpu/topology_common.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,48 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
2424
}
2525
}
2626

27+
static unsigned int __maybe_unused parse_num_cores_legacy(struct cpuinfo_x86 *c)
28+
{
29+
struct {
30+
u32 cache_type : 5,
31+
unused : 21,
32+
ncores : 6;
33+
} eax;
34+
35+
if (c->cpuid_level < 4)
36+
return 1;
37+
38+
cpuid_subleaf_reg(4, 0, CPUID_EAX, &eax);
39+
if (!eax.cache_type)
40+
return 1;
41+
42+
return eax.ncores + 1;
43+
}
44+
45+
static void __maybe_unused parse_legacy(struct topo_scan *tscan)
46+
{
47+
unsigned int cores, core_shift, smt_shift = 0;
48+
struct cpuinfo_x86 *c = tscan->c;
49+
50+
cores = parse_num_cores_legacy(c);
51+
core_shift = get_count_order(cores);
52+
53+
if (cpu_has(c, X86_FEATURE_HT)) {
54+
if (!WARN_ON_ONCE(tscan->ebx1_nproc_shift < core_shift))
55+
smt_shift = tscan->ebx1_nproc_shift - core_shift;
56+
/*
57+
* The parser expects leaf 0xb/0x1f format, which means
58+
* the number of logical processors at core level is
59+
* counting threads.
60+
*/
61+
core_shift += smt_shift;
62+
cores <<= smt_shift;
63+
}
64+
65+
topology_set_dom(tscan, TOPO_SMT_DOMAIN, smt_shift, 1U << smt_shift);
66+
topology_set_dom(tscan, TOPO_CORE_DOMAIN, core_shift, cores);
67+
}
68+
2769
bool topo_is_converted(struct cpuinfo_x86 *c)
2870
{
2971
/* Temporary until everything is converted over. */
@@ -47,7 +89,7 @@ static bool fake_topology(struct topo_scan *tscan)
4789
* which has useless CPUID information.
4890
*/
4991
topology_set_dom(tscan, TOPO_SMT_DOMAIN, 0, 1);
50-
topology_set_dom(tscan, TOPO_CORE_DOMAIN, 1, 1);
92+
topology_set_dom(tscan, TOPO_CORE_DOMAIN, 0, 1);
5193

5294
return tscan->c->cpuid_level < 1 || xen_pv_domain();
5395
}
@@ -88,6 +130,8 @@ static void parse_topology(struct topo_scan *tscan, bool early)
88130
/* The above is sufficient for UP */
89131
if (!IS_ENABLED(CONFIG_SMP))
90132
return;
133+
134+
tscan->ebx1_nproc_shift = get_count_order(ebx.nproc);
91135
}
92136

93137
static void topo_set_ids(struct topo_scan *tscan)

0 commit comments

Comments
 (0)