Skip to content

Commit

Permalink
x86/cpu: Add legacy topology parser
Browse files Browse the repository at this point in the history
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 <tglx@linutronix.de>
Tested-by: Juergen Gross <jgross@suse.com>
Tested-by: Sohil Mehta <sohil.mehta@intel.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Tested-by: Zhang Rui <rui.zhang@intel.com>
Tested-by: Wang Wendy <wendy.wang@intel.com>
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://lore.kernel.org/r/20240212153624.644448852@linutronix.de
  • Loading branch information
Thomas Gleixner committed Feb 15, 2024
1 parent ebdb203 commit bda74aa
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
3 changes: 3 additions & 0 deletions arch/x86/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,9 @@ void detect_ht(struct cpuinfo_x86 *c)
#ifdef CONFIG_SMP
int index_msb, core_bits;

if (topo_is_converted(c))
return;

if (detect_ht_early(c) < 0)
return;

Expand Down
3 changes: 3 additions & 0 deletions arch/x86/kernel/cpu/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ struct topo_scan {
struct cpuinfo_x86 *c;
unsigned int dom_shifts[TOPO_MAX_DOMAIN];
unsigned int dom_ncpus[TOPO_MAX_DOMAIN];

/* Legacy CPUID[1]:EBX[23:16] number of logical processors */
unsigned int ebx1_nproc_shift;
};

bool topo_is_converted(struct cpuinfo_x86 *c);
Expand Down
46 changes: 45 additions & 1 deletion arch/x86/kernel/cpu/topology_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,48 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
}
}

static unsigned int __maybe_unused parse_num_cores_legacy(struct cpuinfo_x86 *c)
{
struct {
u32 cache_type : 5,
unused : 21,
ncores : 6;
} eax;

if (c->cpuid_level < 4)
return 1;

cpuid_subleaf_reg(4, 0, CPUID_EAX, &eax);
if (!eax.cache_type)
return 1;

return eax.ncores + 1;
}

static void __maybe_unused parse_legacy(struct topo_scan *tscan)
{
unsigned int cores, core_shift, smt_shift = 0;
struct cpuinfo_x86 *c = tscan->c;

cores = parse_num_cores_legacy(c);
core_shift = get_count_order(cores);

if (cpu_has(c, X86_FEATURE_HT)) {
if (!WARN_ON_ONCE(tscan->ebx1_nproc_shift < core_shift))
smt_shift = tscan->ebx1_nproc_shift - core_shift;
/*
* The parser expects leaf 0xb/0x1f format, which means
* the number of logical processors at core level is
* counting threads.
*/
core_shift += smt_shift;
cores <<= smt_shift;
}

topology_set_dom(tscan, TOPO_SMT_DOMAIN, smt_shift, 1U << smt_shift);
topology_set_dom(tscan, TOPO_CORE_DOMAIN, core_shift, cores);
}

bool topo_is_converted(struct cpuinfo_x86 *c)
{
/* Temporary until everything is converted over. */
Expand All @@ -47,7 +89,7 @@ static bool fake_topology(struct topo_scan *tscan)
* which has useless CPUID information.
*/
topology_set_dom(tscan, TOPO_SMT_DOMAIN, 0, 1);
topology_set_dom(tscan, TOPO_CORE_DOMAIN, 1, 1);
topology_set_dom(tscan, TOPO_CORE_DOMAIN, 0, 1);

return tscan->c->cpuid_level < 1 || xen_pv_domain();
}
Expand Down Expand Up @@ -88,6 +130,8 @@ static void parse_topology(struct topo_scan *tscan, bool early)
/* The above is sufficient for UP */
if (!IS_ENABLED(CONFIG_SMP))
return;

tscan->ebx1_nproc_shift = get_count_order(ebx.nproc);
}

static void topo_set_ids(struct topo_scan *tscan)
Expand Down

0 comments on commit bda74aa

Please sign in to comment.