@@ -883,6 +883,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;
@@ -7,6 +7,8 @@ struct topo_scan {
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);
@@ -24,6 +24,48 @@ void topology_set_dom(struct topo_scan *
}
}
+static unsigned int parse_num_cores(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(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. */
@@ -88,6 +130,8 @@ static void parse_topology(struct topo_s
/* 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)