@@ -240,12 +240,15 @@ static uint32_t max_processor_ids_for_cache(CPUCacheInfo *cache,
case CORE:
num_ids = 1 << apicid_core_offset(topo_info);
break;
+ case MODULE:
+ num_ids = 1 << apicid_module_offset(topo_info);
+ break;
case DIE:
num_ids = 1 << apicid_die_offset(topo_info);
break;
default:
/*
- * Currently there is no use case for SMT, MODULE and PACKAGE, so use
+ * Currently there is no use case for SMT and PACKAGE, so use
* assert directly to facilitate debugging.
*/
g_assert_not_reached();
@@ -6633,6 +6636,33 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
env->cache_info_amd.l3_cache = &legacy_l3_cache;
}
+ if (cpu->l2_cache_topo_level) {
+ /*
+ * FIXME: Currently only supports changing CPUID[4] (for intel), and
+ * will support changing CPUID[0x8000001D] when necessary.
+ */
+ if (!IS_INTEL_CPU(env)) {
+ error_setg(errp, "only intel cpus supports x-l2-cache-topo");
+ return;
+ }
+
+ if (!strcmp(cpu->l2_cache_topo_level, "core")) {
+ env->cache_info_cpuid4.l2_cache->share_level = CORE;
+ } else if (!strcmp(cpu->l2_cache_topo_level, "cluster")) {
+ /*
+ * We expose to users "cluster" instead of "module", to be
+ * consistent with "cluster-id" naming.
+ */
+ env->cache_info_cpuid4.l2_cache->share_level = MODULE;
+ } else {
+ error_setg(errp,
+ "x-l2-cache-topo doesn't support '%s', "
+ "and it only supports 'core' or 'cluster'",
+ cpu->l2_cache_topo_level);
+ return;
+ }
+ }
+
#ifndef CONFIG_USER_ONLY
MachineState *ms = MACHINE(qdev_get_machine());
qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
@@ -7135,6 +7165,7 @@ static Property x86_cpu_properties[] = {
false),
DEFINE_PROP_BOOL("x-intel-pt-auto-level", X86CPU, intel_pt_auto_level,
true),
+ DEFINE_PROP_STRING("x-l2-cache-topo", X86CPU, l2_cache_topo_level),
DEFINE_PROP_END_OF_LIST()
};
@@ -1987,6 +1987,8 @@ struct ArchCPU {
int32_t thread_id;
int32_t hv_max_vps;
+
+ char *l2_cache_topo_level;
};