@@ -361,6 +361,14 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
topo_ids.die_id = cpu->die_id;
topo_ids.core_id = cpu->core_id;
topo_ids.smt_id = cpu->thread_id;
+
+ /*
+ * TODO: This is the temporary initialization for topo_ids.module_id to
+ * avoid "maybe-uninitialized" compilation errors. Will remove when
+ * X86CPU supports cluster_id.
+ */
+ topo_ids.module_id = 0;
+
cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids);
}
@@ -369,6 +377,11 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
MachineState *ms = MACHINE(x86ms);
x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
+
+ /*
+ * TODO: Before APIC ID supports module level parsing, there's no need
+ * to expose module_id info.
+ */
error_setg(errp,
"Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
" APIC ID %" PRIu32 ", valid index range 0:%d",
@@ -494,6 +507,10 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms)
ms->possible_cpus->cpus[i].props.has_die_id = true;
ms->possible_cpus->cpus[i].props.die_id = topo_ids.die_id;
}
+ if (ms->smp.clusters > 1) {
+ ms->possible_cpus->cpus[i].props.has_cluster_id = true;
+ ms->possible_cpus->cpus[i].props.cluster_id = topo_ids.module_id;
+ }
ms->possible_cpus->cpus[i].props.has_core_id = true;
ms->possible_cpus->cpus[i].props.core_id = topo_ids.core_id;
ms->possible_cpus->cpus[i].props.has_thread_id = true;
@@ -48,6 +48,7 @@ typedef uint32_t apic_id_t;
typedef struct X86CPUTopoIDs {
unsigned pkg_id;
unsigned die_id;
+ unsigned module_id;
unsigned core_id;
unsigned smt_id;
} X86CPUTopoIDs;
@@ -134,12 +135,21 @@ static inline void x86_topo_ids_from_idx(X86CPUTopoInfo *topo_info,
X86CPUTopoIDs *topo_ids)
{
unsigned nr_dies = topo_info->dies_per_pkg;
- unsigned nr_cores = topo_info->cores_per_module *
- topo_info->modules_per_die;
+ unsigned nr_modules = topo_info->modules_per_die;
+ unsigned nr_cores = topo_info->cores_per_module;
unsigned nr_threads = topo_info->threads_per_core;
- topo_ids->pkg_id = cpu_index / (nr_dies * nr_cores * nr_threads);
- topo_ids->die_id = cpu_index / (nr_cores * nr_threads) % nr_dies;
+ /*
+ * Currently smp for i386 doesn't support "clusters", modules_per_die is
+ * only 1. Therefore, the module_id generated from the module topology will
+ * not conflict with the module_id generated according to the apicid.
+ */
+ topo_ids->pkg_id = cpu_index / (nr_dies * nr_modules *
+ nr_cores * nr_threads);
+ topo_ids->die_id = cpu_index / (nr_modules * nr_cores *
+ nr_threads) % nr_dies;
+ topo_ids->module_id = cpu_index / (nr_cores * nr_threads) %
+ nr_modules;
topo_ids->core_id = cpu_index / nr_threads % nr_cores;
topo_ids->smt_id = cpu_index % nr_threads;
}
@@ -156,6 +166,12 @@ static inline void x86_topo_ids_from_apicid(apic_id_t apicid,
topo_ids->core_id =
(apicid >> apicid_core_offset(topo_info)) &
~(0xFFFFFFFFUL << apicid_core_width(topo_info));
+ /*
+ * TODO: This is the temporary initialization for topo_ids.module_id to
+ * avoid "maybe-uninitialized" compilation errors. Will remove when APIC
+ * ID supports module level parsing.
+ */
+ topo_ids->module_id = 0;
topo_ids->die_id =
(apicid >> apicid_die_offset(topo_info)) &
~(0xFFFFFFFFUL << apicid_die_width(topo_info));