From nobody Mon Nov 10 17:35:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.intel.com ARC-Seal: i=1; a=rsa-sha256; t=1558428978; cv=none; d=zoho.com; s=zohoarc; b=IpqIKyaqg7KELKOGiHuKiSBdRYDIhMvQG8CHMOnZP/5jFAGKm+CNaGQW3AdGv/JIWxnH2XmA1BofeemXu22hiAwZUHHJkbX2uIcWoitafZhfBw/pnA3wN/WiUxK65EBalsadKac+oR9A+lgfI/Ntopr+t8WylxNOgKmSbyeGS7s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558428978; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=1F92bPoP32gyRdjZwLE8GKnqNALk5sQKn1tZ2YJMw9Q=; b=dKsBwUQp/zTRCMy33ayk/zPVPFyNt9yKAZq/LFUjjb1gqoMLKJEkqJH6dWsJiONl1OO115NfkqjtHVNRwvbGOZMOLsOzdS14F7d8RpFG+XPzPNi8/IAssdb3XYIDGMMAqlC57rLM6G/vw6+FJoY1MADcTMcwxxQykwCOmx+ZjzU= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558428978541301.77836167293344; Tue, 21 May 2019 01:56:18 -0700 (PDT) Received: from localhost ([127.0.0.1]:49279 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0YZ-0002yT-I5 for importer@patchew.org; Tue, 21 May 2019 04:55:35 -0400 Received: from eggs.gnu.org ([209.51.188.92]:52004) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0WD-0001NZ-EI for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hT0W7-0000Z4-Ql for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:09 -0400 Received: from mga04.intel.com ([192.55.52.120]:1679) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hT0W7-0000UM-Gw for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:03 -0400 Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 May 2019 01:52:58 -0700 Received: from clx-ap-likexu.sh.intel.com ([10.239.48.98]) by fmsmga007.fm.intel.com with ESMTP; 21 May 2019 01:52:56 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 From: Like Xu To: qemu-devel@nongnu.org Date: Tue, 21 May 2019 00:50:52 +0800 Message-Id: <20190520165056.175475-2-like.xu@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520165056.175475-1-like.xu@linux.intel.com> References: <20190520165056.175475-1-like.xu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.120 Subject: [Qemu-devel] [PATCH v2 1/5] target/i386: Add cpu die-level topology support for X86CPU X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jones , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , Eduardo Habkost , Peter Crosthwaite , Marcelo Tosatti , "Dr . David Alan Gilbert" , Markus Armbruster , Brice Goglin , Paolo Bonzini , Igor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The die-level as the first PC-specific cpu topology is added to the leagcy cpu topology model which only covers sockets/cores/threads. In the new model with die-level support, the total number of logical processors (including offline) on board will be calculated as: #cpus =3D #sockets * #dies * #cores * #threads and considering compatibility, the default value for #dies is 1. A new set of die-related variables are added in smp context and the CPUX86State.nr_dies is assigned in x86_cpu_initfn() from PCMachineState. Signed-off-by: Like Xu --- hw/i386/pc.c | 3 +++ include/hw/i386/pc.h | 2 ++ include/hw/i386/topology.h | 2 ++ qapi/misc.json | 6 ++++-- target/i386/cpu.c | 9 +++++++++ target/i386/cpu.h | 3 +++ 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 896c22e32e..83ab53c814 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2341,6 +2341,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_d= ev, =20 topo.pkg_id =3D cpu->socket_id; topo.core_id =3D cpu->core_id; + topo.die_id =3D cpu->die_id; topo.smt_id =3D cpu->thread_id; cpu->apic_id =3D apicid_from_topo_ids(smp_cores, smp_threads, &top= o); } @@ -2692,6 +2693,8 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(= MachineState *ms) ms->smp.cores, ms->smp.threads, &topo); ms->possible_cpus->cpus[i].props.has_socket_id =3D true; ms->possible_cpus->cpus[i].props.socket_id =3D topo.pkg_id; + ms->possible_cpus->cpus[i].props.has_die_id =3D true; + ms->possible_cpus->cpus[i].props.die_id =3D topo.die_id; ms->possible_cpus->cpus[i].props.has_core_id =3D true; ms->possible_cpus->cpus[i].props.core_id =3D topo.core_id; ms->possible_cpus->cpus[i].props.has_thread_id =3D true; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index ce3c22951e..b5faf2ede9 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -24,6 +24,7 @@ * PCMachineState: * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling * @boot_cpus: number of present VCPUs + * @smp_dies: number of dies per one package */ struct PCMachineState { /*< private >*/ @@ -59,6 +60,7 @@ struct PCMachineState { bool apic_xrupt_override; unsigned apic_id_limit; uint16_t boot_cpus; + unsigned smp_dies; =20 /* NUMA information: */ uint64_t numa_nodes; diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index 1ebaee0f76..7f80498eb3 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -47,6 +47,7 @@ typedef uint32_t apic_id_t; =20 typedef struct X86CPUTopoInfo { unsigned pkg_id; + unsigned die_id; unsigned core_id; unsigned smt_id; } X86CPUTopoInfo; @@ -130,6 +131,7 @@ static inline void x86_topo_ids_from_apicid(apic_id_t a= picid, topo->core_id =3D (apicid >> apicid_core_offset(nr_cores, nr_threads))= & ~(0xFFFFFFFFUL << apicid_core_width(nr_cores, nr_thread= s)); topo->pkg_id =3D apicid >> apicid_pkg_offset(nr_cores, nr_threads); + topo->die_id =3D -1; } =20 /* Make APIC ID for the CPU 'cpu_index' diff --git a/qapi/misc.json b/qapi/misc.json index 8b3ca4fdd3..cd236c89b3 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -2924,10 +2924,11 @@ # # @node-id: NUMA node ID the CPU belongs to # @socket-id: socket number within node/board the CPU belongs to -# @core-id: core number within socket the CPU belongs to +# @die-id: die number within node/board the CPU belongs to (Since 4.1) +# @core-id: core number within die the CPU belongs to # @thread-id: thread number within core the CPU belongs to # -# Note: currently there are 4 properties that could be present +# Note: currently there are 5 properties that could be present # but management should be prepared to pass through other # properties with device_add command to allow for future # interface extension. This also requires the filed names to be kept in @@ -2938,6 +2939,7 @@ { 'struct': 'CpuInstanceProperties', 'data': { '*node-id': 'int', '*socket-id': 'int', + '*die-id': 'int', '*core-id': 'int', '*thread-id': 'int' } diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 9a93dd8be7..9bd35b4965 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -55,6 +55,7 @@ #include "hw/xen/xen.h" #include "hw/i386/apic_internal.h" #include "hw/boards.h" +#include "hw/i386/pc.h" #endif =20 #include "disas/capstone.h" @@ -5595,7 +5596,13 @@ static void x86_cpu_initfn(Object *obj) X86CPUClass *xcc =3D X86_CPU_GET_CLASS(obj); CPUX86State *env =3D &cpu->env; FeatureWord w; +#ifndef CONFIG_USER_ONLY + MachineState *machine =3D MACHINE(qdev_get_machine()); + PCMachineState *pcms =3D (PCMachineState *) + object_dynamic_cast(OBJECT(machine), TYPE_PC_MACHINE); =20 + env->nr_dies =3D pcms ? pcms->smp_dies : 1; +#endif cs->env_ptr =3D env; =20 object_property_add(obj, "family", "int", @@ -5812,11 +5819,13 @@ static Property x86_cpu_properties[] =3D { DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0), DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, 0), DEFINE_PROP_INT32("core-id", X86CPU, core_id, 0), + DEFINE_PROP_INT32("die-id", X86CPU, die_id, 0), DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, 0), #else DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID), DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, -1), DEFINE_PROP_INT32("core-id", X86CPU, core_id, -1), + DEFINE_PROP_INT32("die-id", X86CPU, die_id, -1), DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, -1), #endif DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID), diff --git a/target/i386/cpu.h b/target/i386/cpu.h index fce6660bac..d5f2a60ff5 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1361,6 +1361,8 @@ typedef struct CPUX86State { uint64_t xss; =20 TPRAccess tpr_access_type; + + unsigned nr_dies; } CPUX86State; =20 struct kvm_msrs; @@ -1484,6 +1486,7 @@ struct X86CPU { =20 int32_t node_id; /* NUMA node this CPU belongs to */ int32_t socket_id; + int32_t die_id; int32_t core_id; int32_t thread_id; =20 --=20 2.21.0 From nobody Mon Nov 10 17:35:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.intel.com ARC-Seal: i=1; a=rsa-sha256; t=1558428930; cv=none; d=zoho.com; s=zohoarc; b=Jodf3J+4WsVLtenFxVph7B6mfU0U7NZOYcT19TZgxwKViOZKQcfIbHilpPkACQ/Ig2fR4qgImgPTgEuHm3rDMPWN+YRpiV8yRmhohtvXmiXXlkby+cXwp+8EPyrcLlo9y8YkwJfVfICCeXOVXt4LxukCQKBMHgflK9gN+Eh68So= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558428930; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=IsF9cLxKi88VEp2hLEEY8eIn5aGmdV3008vAKJz3A34=; b=crWrI7+gWV73kSnVaDsLICGCmHUCiESo3TCnJ0j1gUaRdwB5JdeZ84eOJ6xaxOD41v+8hL3HTN51AUtF4jpzUxApeN5YQF9gRw1f70Gs6z9S5ojhw5xyQtZ4ic7a8Li1RcXR+FzYkJKq/cVcZvhTI/pY47LR8T1g2YNDnGvKWHo= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558428929840733.6451018011287; Tue, 21 May 2019 01:55:29 -0700 (PDT) Received: from localhost ([127.0.0.1]:49271 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0YM-0002nu-LS for importer@patchew.org; Tue, 21 May 2019 04:55:22 -0400 Received: from eggs.gnu.org ([209.51.188.92]:51885) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0W8-0001J8-8S for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hT0W7-0000Xm-1x for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:04 -0400 Received: from mga04.intel.com ([192.55.52.120]:1682) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hT0W6-0000W3-QC for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:02 -0400 Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 May 2019 01:53:00 -0700 Received: from clx-ap-likexu.sh.intel.com ([10.239.48.98]) by fmsmga007.fm.intel.com with ESMTP; 21 May 2019 01:52:58 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 From: Like Xu To: qemu-devel@nongnu.org Date: Tue, 21 May 2019 00:50:53 +0800 Message-Id: <20190520165056.175475-3-like.xu@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520165056.175475-1-like.xu@linux.intel.com> References: <20190520165056.175475-1-like.xu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.120 Subject: [Qemu-devel] [PATCH v2 2/5] i386/cpu: Consolidate die-id validity in smp context X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jones , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , Eduardo Habkost , Peter Crosthwaite , Marcelo Tosatti , "Dr . David Alan Gilbert" , Markus Armbruster , Brice Goglin , Paolo Bonzini , Igor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Following the legacy smp check rules, the die_id validity is added to the same contexts as leagcy smp variables such as hmp_hotpluggable_cpus(), machine_set_cpu_numa_node(), cpu_slot_to_string() and pc_cpu_pre_plug(). Signed-off-by: Like Xu Acked-by: Dr. David Alan Gilbert --- hmp.c | 3 +++ hw/core/machine.c | 12 ++++++++++++ hw/i386/pc.c | 11 +++++++++++ 3 files changed, 26 insertions(+) diff --git a/hmp.c b/hmp.c index 56a3ed7375..7deb7b7226 100644 --- a/hmp.c +++ b/hmp.c @@ -3112,6 +3112,9 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict = *qdict) if (c->has_socket_id) { monitor_printf(mon, " socket-id: \"%" PRIu64 "\"\n", c->soc= ket_id); } + if (c->has_die_id) { + monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id= ); + } if (c->has_core_id) { monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_= id); } diff --git a/hw/core/machine.c b/hw/core/machine.c index 5d046a43e3..5116429732 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -659,6 +659,11 @@ void machine_set_cpu_numa_node(MachineState *machine, return; } =20 + if (props->has_die_id && !slot->props.has_die_id) { + error_setg(errp, "die-id is not supported"); + return; + } + /* skip slots with explicit mismatch */ if (props->has_thread_id && props->thread_id !=3D slot->props.thre= ad_id) { continue; @@ -668,6 +673,10 @@ void machine_set_cpu_numa_node(MachineState *machine, continue; } =20 + if (props->has_die_id && props->die_id !=3D slot->props.die_id) { + continue; + } + if (props->has_socket_id && props->socket_id !=3D slot->props.sock= et_id) { continue; } @@ -925,6 +934,9 @@ static char *cpu_slot_to_string(const CPUArchId *cpu) if (cpu->props.has_socket_id) { g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_= id); } + if (cpu->props.has_die_id) { + g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id); + } if (cpu->props.has_core_id) { if (s->len) { g_string_append_printf(s, ", "); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 83ab53c814..00be2463af 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2321,6 +2321,10 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_= dev, error_setg(errp, "Invalid CPU socket-id: %u must be in range 0= :%u", cpu->socket_id, max_socket); return; + } else if (cpu->die_id > max_socket) { + error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u= ", + cpu->die_id, max_socket); + return; } if (cpu->core_id < 0) { error_setg(errp, "CPU core-id is not set"); @@ -2378,6 +2382,13 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_= dev, } cpu->socket_id =3D topo.pkg_id; =20 + if (cpu->die_id !=3D -1 && cpu->die_id !=3D topo.die_id) { + error_setg(errp, "property die-id: %u doesn't match set apic-id:" + " 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo.die_id); + return; + } + cpu->die_id =3D topo.die_id; + if (cpu->core_id !=3D -1 && cpu->core_id !=3D topo.core_id) { error_setg(errp, "property core-id: %u doesn't match set apic-id:" " 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, topo.core_i= d); --=20 2.21.0 From nobody Mon Nov 10 17:35:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.intel.com ARC-Seal: i=1; a=rsa-sha256; t=1558429078; cv=none; d=zoho.com; s=zohoarc; b=oPBPrlfXujM913YEg8hb3F/Z3NpMHCMnbka7MOLSuEGWEvjzxxUpUUTF+rtvSP/vI5zG0rFoe++1yC9M09++Ah1GbnPJsvKI3YPiHuAHYkaOnhM9Edv33LHLHjtSXUEArOXQpn1B5OENFZTnm618GKCFpr4z34vVEBj7gnNX7OI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558429078; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=uIhydZd0wgmYqrtu9FuR9xXvhevAlwDW64LGmK6SVYQ=; b=f5BpIqyemgrzxQChM1n8h6iREZdkKhUk1BL0RQHXLaHGYfaeIO95PLiBrY+ha0r8gXc5bmzkJy3wUDwBRbHV40iv6o+stXc2pPO5+t59WvWfQUe62wzwq2DB+dk36vr7eRbc0fNkEj7kyz9c20ZKBZUoAFIlMs0Cz++zqUbiGA8= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558429078199378.09948902684755; Tue, 21 May 2019 01:57:58 -0700 (PDT) Received: from localhost ([127.0.0.1]:49395 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0al-0004xj-5U for importer@patchew.org; Tue, 21 May 2019 04:57:51 -0400 Received: from eggs.gnu.org ([209.51.188.92]:51959) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0WA-0001L5-4G for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hT0W8-0000aQ-Ce for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:06 -0400 Received: from mga04.intel.com ([192.55.52.120]:1679) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hT0W8-0000UM-3A for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:04 -0400 Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 May 2019 01:53:03 -0700 Received: from clx-ap-likexu.sh.intel.com ([10.239.48.98]) by fmsmga007.fm.intel.com with ESMTP; 21 May 2019 01:53:01 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 From: Like Xu To: qemu-devel@nongnu.org Date: Tue, 21 May 2019 00:50:54 +0800 Message-Id: <20190520165056.175475-4-like.xu@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520165056.175475-1-like.xu@linux.intel.com> References: <20190520165056.175475-1-like.xu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.120 Subject: [Qemu-devel] [PATCH v2 3/5] vl.c: Add -smp, dies=* command line support and update -smp doc X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jones , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , Eduardo Habkost , Peter Crosthwaite , Marcelo Tosatti , "Dr . David Alan Gilbert" , Markus Armbruster , Brice Goglin , Paolo Bonzini , Igor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" For PC target, users could configure the number of dies per one package via command line with this patch, such as "-smp dies=3D2,cores=3D4". A new pc-specified pc_smp_parse() is introduced and to keep the interface consistent, refactoring legacy smp_parse() to __smp_parse() is necessary. The parsing rules of new cpu-topology model obey the same restrictions/logic as the legacy socket/core/thread model especially on missing values computi= ng. Signed-off-by: Like Xu --- qemu-options.hx | 17 +++++----- vl.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 5daa5a8fb0..7fad5b50ff 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -138,25 +138,26 @@ no incompatible TCG features have been enabled (e.g. = icount/replay). ETEXI =20 DEF("smp", HAS_ARG, QEMU_OPTION_smp, - "-smp [cpus=3D]n[,maxcpus=3Dcpus][,cores=3Dcores][,threads=3Dthreads][= ,sockets=3Dsockets]\n" + "-smp [cpus=3D]n[,maxcpus=3Dcpus][,cores=3Dcores][,threads=3Dthreads][= ,dies=3Ddies][,sockets=3Dsockets]\n" " set the number of CPUs to 'n' [default=3D1]\n" " maxcpus=3D maximum number of total cpus, including\n" " offline CPUs for hotplug, etc\n" - " cores=3D number of CPU cores on one socket\n" + " cores=3D number of CPU cores on one socket (for PC, i= t's on one die)\n" " threads=3D number of threads on one CPU core\n" + " dies=3D number of CPU dies on one socket (for PC only= )\n" " sockets=3D number of discrete sockets in the system\n= ", QEMU_ARCH_ALL) STEXI -@item -smp [cpus=3D]@var{n}[,cores=3D@var{cores}][,threads=3D@var{threads}= ][,sockets=3D@var{sockets}][,maxcpus=3D@var{maxcpus}] +@item -smp [cpus=3D]@var{n}[,cores=3D@var{cores}][,threads=3D@var{threads}= ][,dies=3Ddies][,sockets=3D@var{sockets}][,maxcpus=3D@var{maxcpus}] @findex -smp Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255 CPUs are supported. On Sparc32 target, Linux limits the number of usable C= PUs to 4. -For the PC target, the number of @var{cores} per socket, the number -of @var{threads} per cores and the total number of @var{sockets} can be -specified. Missing values will be computed. If any on the three values is -given, the total number of CPUs @var{n} can be omitted. @var{maxcpus} -specifies the maximum number of hotpluggable CPUs. +For the PC target, the number of @var{cores} per die, the number of @var{t= hreads} +per cores, the number of @var{dies} per packages and the total number of +@var{sockets} can be specified. Missing values will be computed. +If any on the three values is given, the total number of CPUs @var{n} can = be omitted. +@var{maxcpus} specifies the maximum number of hotpluggable CPUs. ETEXI =20 DEF("numa", HAS_ARG, QEMU_OPTION_numa, diff --git a/vl.c b/vl.c index 8d92e2d209..66b577f447 100644 --- a/vl.c +++ b/vl.c @@ -63,6 +63,7 @@ int main(int argc, char **argv) #include "sysemu/watchdog.h" #include "hw/firmware/smbios.h" #include "hw/acpi/acpi.h" +#include "hw/i386/pc.h" #include "hw/xen/xen.h" #include "hw/qdev.h" #include "hw/loader.h" @@ -1248,6 +1249,9 @@ static QemuOptsList qemu_smp_opts =3D { }, { .name =3D "sockets", .type =3D QEMU_OPT_NUMBER, + }, { + .name =3D "dies", + .type =3D QEMU_OPT_NUMBER, }, { .name =3D "cores", .type =3D QEMU_OPT_NUMBER, @@ -1262,7 +1266,7 @@ static QemuOptsList qemu_smp_opts =3D { }, }; =20 -static void smp_parse(QemuOpts *opts) +static void __smp_parse(QemuOpts *opts) { if (opts) { unsigned cpus =3D qemu_opt_get_number(opts, "cpus", 0); @@ -1334,6 +1338,89 @@ static void smp_parse(QemuOpts *opts) } } =20 +static void pc_smp_parse(QemuOpts *opts) +{ + PCMachineState *pcms =3D (PCMachineState *) + object_dynamic_cast(OBJECT(current_machine), TYPE_PC_MACHINE); + + unsigned cpus =3D qemu_opt_get_number(opts, "cpus", 0); + unsigned sockets =3D qemu_opt_get_number(opts, "sockets", 0); + unsigned dies =3D qemu_opt_get_number(opts, "dies", 1); + unsigned cores =3D qemu_opt_get_number(opts, "cores", 0); + unsigned threads =3D qemu_opt_get_number(opts, "threads", 0); + + /* compute missing values, prefer sockets over cores over threads */ + if (cpus =3D=3D 0 || sockets =3D=3D 0) { + cores =3D cores > 0 ? cores : 1; + threads =3D threads > 0 ? threads : 1; + if (cpus =3D=3D 0) { + sockets =3D sockets > 0 ? sockets : 1; + cpus =3D cores * threads * dies * sockets; + } else { + current_machine->smp.max_cpus =3D + qemu_opt_get_number(opts, "maxcpus", cpus); + sockets =3D current_machine->smp.max_cpus / (cores * threads *= dies); + } + } else if (cores =3D=3D 0) { + threads =3D threads > 0 ? threads : 1; + cores =3D cpus / (sockets * dies * threads); + cores =3D cores > 0 ? cores : 1; + } else if (threads =3D=3D 0) { + threads =3D cpus / (cores * dies * sockets); + threads =3D threads > 0 ? threads : 1; + } else if (sockets * dies * cores * threads < cpus) { + error_report("cpu topology: " + "sockets (%u) * dies (%u) * cores (%u) * threads (= %u) < " + "smp_cpus (%u)", + sockets, dies, cores, threads, cpus); + exit(1); + } + + current_machine->smp.max_cpus =3D + qemu_opt_get_number(opts, "maxcpus", cpus); + + if (current_machine->smp.max_cpus < cpus) { + error_report("maxcpus must be equal to or greater than smp"); + exit(1); + } + + if (sockets * dies * cores * threads > current_machine->smp.max_cpus) { + error_report("cpu topology: " + "sockets (%u) * dies (%u) * cores (%u) * threads (= %u) > " + "maxcpus (%u)", + sockets, dies, cores, threads, + current_machine->smp.max_cpus); + exit(1); + } + + if (sockets * dies * cores * threads !=3D current_machine->smp.max_cpu= s) { + warn_report("Invalid CPU topology deprecated: " + "sockets (%u) * dies (%u) * cores (%u) * threads (%u) " + "!=3D maxcpus (%u)", + sockets, dies, cores, threads, + current_machine->smp.max_cpus); + } + + current_machine->smp.cpus =3D cpus; + current_machine->smp.cores =3D cores; + current_machine->smp.threads =3D threads; + pcms->smp_dies =3D dies; + + if (current_machine->smp.cpus > 1) { + Error *blocker =3D NULL; + error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); + replay_add_blocker(blocker); + } +} + +static void smp_parse(QemuOpts *opts) +{ + if (object_dynamic_cast(OBJECT(current_machine), TYPE_PC_MACHINE)) + pc_smp_parse(opts); + else + __smp_parse(opts); +} + static void realtime_init(void) { if (enable_mlock) { --=20 2.21.0 From nobody Mon Nov 10 17:35:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.intel.com ARC-Seal: i=1; a=rsa-sha256; t=1558429215; cv=none; d=zoho.com; s=zohoarc; b=Ge8/WrR2AEoj19eiRqhht7VFvkr1W4KE/3IrILiuFItjIhLnupFzkCZq6EfP1vgOOG2pBRZ/YI/naoV8+foInhQgatrm6jXGwQ242ImFqlH/Ff5xmMQlmOAs+Twaudq52L2mIsRHwyrxPq+VbOXe7z+akiQajTn7dStMrLW+N7Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558429215; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=JPW9Y2Q4BIQZNiIRtSxDRnoMEK9h/yvT19WWQGjHaH8=; b=Cc4NTjy4dZYxYGbDND4ywuSs+arvMJUMDFUwEVBCvEGXhMpf9xQZO0/PMLXGfBnz60WksQsQ8NnXw8tKoM3uqYj4Ef9TJp3npmhI2rcxFmBhH28MwdFKpi8VWI5bTv4EYi6Fgt232sY1PwnjV42vqqfif0ZPCgYvT3XKOcXSUqA= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558429215796233.60570034837428; Tue, 21 May 2019 02:00:15 -0700 (PDT) Received: from localhost ([127.0.0.1]:49519 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0cy-0006nv-Ns for importer@patchew.org; Tue, 21 May 2019 05:00:08 -0400 Received: from eggs.gnu.org ([209.51.188.92]:51999) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0WD-0001NY-7W for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hT0WB-0000eM-0C for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:09 -0400 Received: from mga04.intel.com ([192.55.52.120]:1689) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hT0WA-0000dP-Hx for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:06 -0400 Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 May 2019 01:53:05 -0700 Received: from clx-ap-likexu.sh.intel.com ([10.239.48.98]) by fmsmga007.fm.intel.com with ESMTP; 21 May 2019 01:53:03 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 From: Like Xu To: qemu-devel@nongnu.org Date: Tue, 21 May 2019 00:50:55 +0800 Message-Id: <20190520165056.175475-5-like.xu@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520165056.175475-1-like.xu@linux.intel.com> References: <20190520165056.175475-1-like.xu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.120 Subject: [Qemu-devel] [PATCH v2 4/5] i386/cpu: Update apicid parsing rules and topo-bit tests for dies X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jones , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , Eduardo Habkost , Peter Crosthwaite , Marcelo Tosatti , "Dr . David Alan Gilbert" , Markus Armbruster , Brice Goglin , Paolo Bonzini , Igor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" On Intel MCP (Multi-chip packaging) platforms, the apicid of logical cpu would imply die level info of cpu topology thus x86_apicid_from_cpu_idx() should be refactored with virtual nr_dies, so does apicid_*_offset(). To maintain semantic consistency, the pkg_offset which helps to generate CPUIDs such as 0x3 for L3 cache is mapping to die_offset from this commit. The corresponding topo_bits tests are updated to test die configurations. Signed-off-by: Like Xu --- hw/i386/pc.c | 38 +++++++++++------ include/hw/i386/topology.h | 76 ++++++++++++++++++++++++---------- target/i386/cpu.c | 13 +++--- tests/test-x86-cpuid.c | 84 ++++++++++++++++++++------------------ 4 files changed, 133 insertions(+), 78 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 00be2463af..e498334cbc 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -935,10 +935,11 @@ void enable_compat_apic_id_mode(void) static uint32_t x86_cpu_apic_id_from_index(MachineState *ms, unsigned int cpu_index) { + PCMachineState *pcms =3D PC_MACHINE(ms); uint32_t correct_id; static bool warned; =20 - correct_id =3D x86_apicid_from_cpu_idx(ms->smp.cores, + correct_id =3D x86_apicid_from_cpu_idx(pcms->smp_dies, ms->smp.cores, ms->smp.threads, cpu_index); if (compat_apic_id_mode) { if (cpu_index !=3D correct_id && !warned && !qtest_enabled()) { @@ -2303,6 +2304,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_d= ev, PCMachineState *pcms =3D PC_MACHINE(hotplug_dev); unsigned int smp_cores =3D ms->smp.cores; unsigned int smp_threads =3D ms->smp.threads; + unsigned int smp_dies =3D pcms->smp_dies; =20 if(!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", @@ -2310,9 +2312,13 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_= dev, return; } =20 - /* if APIC ID is not set, set it based on socket/core/thread propertie= s */ + /* + * If APIC ID is not set, + * set it based on socket/die/core/thread properties. + */ if (cpu->apic_id =3D=3D UNASSIGNED_APIC_ID) { - int max_socket =3D (ms->smp.max_cpus - 1) / smp_threads / smp_core= s; + int max_socket =3D (ms->smp.max_cpus - 1) / + smp_threads / smp_cores / pcms->smp_dies; =20 if (cpu->socket_id < 0) { error_setg(errp, "CPU socket-id is not set"); @@ -2347,18 +2353,21 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug= _dev, topo.core_id =3D cpu->core_id; topo.die_id =3D cpu->die_id; topo.smt_id =3D cpu->thread_id; - cpu->apic_id =3D apicid_from_topo_ids(smp_cores, smp_threads, &top= o); + cpu->apic_id =3D apicid_from_topo_ids(smp_dies, smp_cores, + smp_threads, &topo); } =20 cpu_slot =3D pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, &idx); if (!cpu_slot) { MachineState *ms =3D MACHINE(pcms); =20 - x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &to= po); - error_setg(errp, "Invalid CPU [socket: %u, core: %u, thread: %u] w= ith" - " APIC ID %" PRIu32 ", valid index range 0:%d", - topo.pkg_id, topo.core_id, topo.smt_id, cpu->apic_id, - ms->possible_cpus->len - 1); + x86_topo_ids_from_apicid(cpu->apic_id, smp_dies, + smp_cores, smp_threads, &topo); + error_setg(errp, + "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with" + " APIC ID %" PRIu32 ", valid index range 0:%d", + topo.pkg_id, topo.die_id, topo.core_id, topo.smt_id, + cpu->apic_id, ms->possible_cpus->len - 1); return; } =20 @@ -2374,7 +2383,8 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_d= ev, /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizef= n() * once -smp refactoring is complete and there will be CPU private * CPUState::nr_cores and CPUState::nr_threads fields instead of globa= ls */ - x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo); + x86_topo_ids_from_apicid(cpu->apic_id, smp_dies, + smp_cores, smp_threads, &topo); if (cpu->socket_id !=3D -1 && cpu->socket_id !=3D topo.pkg_id) { error_setg(errp, "property socket-id: %u doesn't match set apic-id= :" " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, topo.pk= g_id); @@ -2670,10 +2680,12 @@ pc_cpu_index_to_props(MachineState *ms, unsigned cp= u_index) static int64_t pc_get_default_cpu_node_id(const MachineState *ms, int idx) { X86CPUTopoInfo topo; + PCMachineState *pcms =3D PC_MACHINE(ms); =20 assert(idx < ms->possible_cpus->len); x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, - ms->smp.cores, ms->smp.threads, &topo); + pcms->smp_dies, ms->smp.cores, + ms->smp.threads, &topo); return topo.pkg_id % nb_numa_nodes; } =20 @@ -2681,6 +2693,7 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(= MachineState *ms) { int i; unsigned int max_cpus =3D ms->smp.max_cpus; + PCMachineState *pcms =3D PC_MACHINE(ms); =20 if (ms->possible_cpus) { /* @@ -2701,7 +2714,8 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(= MachineState *ms) ms->possible_cpus->cpus[i].vcpus_count =3D 1; ms->possible_cpus->cpus[i].arch_id =3D x86_cpu_apic_id_from_index(= ms, i); x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, - ms->smp.cores, ms->smp.threads, &topo); + pcms->smp_dies, ms->smp.cores, + ms->smp.threads, &topo); ms->possible_cpus->cpus[i].props.has_socket_id =3D true; ms->possible_cpus->cpus[i].props.socket_id =3D topo.pkg_id; ms->possible_cpus->cpus[i].props.has_die_id =3D true; diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index 7f80498eb3..4ff5b2da6c 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -63,88 +63,120 @@ static unsigned apicid_bitwidth_for_count(unsigned cou= nt) =20 /* Bit width of the SMT_ID (thread ID) field on the APIC ID */ -static inline unsigned apicid_smt_width(unsigned nr_cores, unsigned nr_thr= eads) +static inline unsigned apicid_smt_width(unsigned nr_dies, + unsigned nr_cores, + unsigned nr_threads) { return apicid_bitwidth_for_count(nr_threads); } =20 /* Bit width of the Core_ID field */ -static inline unsigned apicid_core_width(unsigned nr_cores, unsigned nr_th= reads) +static inline unsigned apicid_core_width(unsigned nr_dies, + unsigned nr_cores, + unsigned nr_threads) { return apicid_bitwidth_for_count(nr_cores); } =20 +/* Bit width of the Die_ID field */ +static inline unsigned apicid_die_width(unsigned nr_dies, + unsigned nr_cores, + unsigned nr_threads) +{ + return apicid_bitwidth_for_count(nr_dies); +} + /* Bit offset of the Core_ID field */ -static inline unsigned apicid_core_offset(unsigned nr_cores, +static inline unsigned apicid_core_offset(unsigned nr_dies, + unsigned nr_cores, unsigned nr_threads) { - return apicid_smt_width(nr_cores, nr_threads); + return apicid_smt_width(nr_dies, nr_cores, nr_threads); +} + +/* Bit offset of the Die_ID field */ +static inline unsigned apicid_die_offset(unsigned nr_dies, + unsigned nr_cores, + unsigned nr_threads) +{ + return apicid_core_offset(nr_dies, nr_cores, nr_threads) + + apicid_core_width(nr_dies, nr_cores, nr_threads); } =20 /* Bit offset of the Pkg_ID (socket ID) field */ -static inline unsigned apicid_pkg_offset(unsigned nr_cores, unsigned nr_th= reads) +static inline unsigned apicid_pkg_offset(unsigned nr_dies, + unsigned nr_cores, + unsigned nr_threads) { - return apicid_core_offset(nr_cores, nr_threads) + - apicid_core_width(nr_cores, nr_threads); + return apicid_die_offset(nr_dies, nr_cores, nr_threads) + + apicid_die_width(nr_dies, nr_cores, nr_threads); } =20 /* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID * * The caller must make sure core_id < nr_cores and smt_id < nr_threads. */ -static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores, +static inline apic_id_t apicid_from_topo_ids(unsigned nr_dies, + unsigned nr_cores, unsigned nr_threads, const X86CPUTopoInfo *topo) { - return (topo->pkg_id << apicid_pkg_offset(nr_cores, nr_threads)) | - (topo->core_id << apicid_core_offset(nr_cores, nr_threads)) | + return (topo->pkg_id << apicid_pkg_offset(nr_dies, nr_cores, nr_threa= ds)) | + (topo->die_id << apicid_die_offset(nr_dies, nr_cores, nr_threa= ds)) | + (topo->core_id << apicid_core_offset(nr_dies, nr_cores, nr_threa= ds)) | topo->smt_id; } =20 /* Calculate thread/core/package IDs for a specific topology, * based on (contiguous) CPU index */ -static inline void x86_topo_ids_from_idx(unsigned nr_cores, +static inline void x86_topo_ids_from_idx(unsigned nr_dies, + unsigned nr_cores, unsigned nr_threads, unsigned cpu_index, X86CPUTopoInfo *topo) { - unsigned core_index =3D cpu_index / nr_threads; + topo->pkg_id =3D cpu_index / (nr_dies * nr_cores * nr_threads); + topo->die_id =3D cpu_index / (nr_cores * nr_threads) % nr_dies; + topo->core_id =3D cpu_index / nr_threads % nr_cores; topo->smt_id =3D cpu_index % nr_threads; - topo->core_id =3D core_index % nr_cores; - topo->pkg_id =3D core_index / nr_cores; } =20 /* Calculate thread/core/package IDs for a specific topology, * based on APIC ID */ static inline void x86_topo_ids_from_apicid(apic_id_t apicid, + unsigned nr_dies, unsigned nr_cores, unsigned nr_threads, X86CPUTopoInfo *topo) { topo->smt_id =3D apicid & - ~(0xFFFFFFFFUL << apicid_smt_width(nr_cores, nr_threads= )); - topo->core_id =3D (apicid >> apicid_core_offset(nr_cores, nr_threads))= & - ~(0xFFFFFFFFUL << apicid_core_width(nr_cores, nr_thread= s)); - topo->pkg_id =3D apicid >> apicid_pkg_offset(nr_cores, nr_threads); - topo->die_id =3D -1; + ~(0xFFFFFFFFUL << apicid_smt_width(nr_dies, nr_cores, nr_threa= ds)); + topo->core_id =3D + (apicid >> apicid_core_offset(nr_dies, nr_cores, nr_threads)) & + ~(0xFFFFFFFFUL << apicid_core_width(nr_dies, nr_cores, nr_thre= ads)); + topo->die_id =3D + (apicid >> apicid_die_offset(nr_dies, nr_cores, nr_threads)) & + ~(0xFFFFFFFFUL << apicid_die_width(nr_dies, nr_cores, nr_threa= ds)); + topo->pkg_id =3D apicid >> apicid_pkg_offset(nr_dies, nr_cores, nr_thr= eads); } =20 /* Make APIC ID for the CPU 'cpu_index' * * 'cpu_index' is a sequential, contiguous ID for the CPU. */ -static inline apic_id_t x86_apicid_from_cpu_idx(unsigned nr_cores, +static inline apic_id_t x86_apicid_from_cpu_idx(unsigned nr_dies, + unsigned nr_cores, unsigned nr_threads, unsigned cpu_index) { X86CPUTopoInfo topo; - x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index, &topo); - return apicid_from_topo_ids(nr_cores, nr_threads, &topo); + x86_topo_ids_from_idx(nr_dies, nr_cores, nr_threads, cpu_index, &topo); + return apicid_from_topo_ids(nr_dies, nr_cores, nr_threads, &topo); } =20 #endif /* HW_I386_TOPOLOGY_H */ diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 9bd35b4965..3222bd3254 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -4225,7 +4225,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, = uint32_t count, { X86CPU *cpu =3D x86_env_get_cpu(env); CPUState *cs =3D CPU(cpu); - uint32_t pkg_offset; + uint32_t die_offset; uint32_t limit; uint32_t signature[3]; =20 @@ -4314,10 +4314,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index= , uint32_t count, eax, ebx, ecx, edx); break; case 3: /* L3 cache info */ - pkg_offset =3D apicid_pkg_offset(cs->nr_cores, cs->nr_thre= ads); + die_offset =3D apicid_die_offset(env->nr_dies, + cs->nr_cores, cs->nr_threads); if (cpu->enable_l3_cache) { encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache, - (1 << pkg_offset), cs->nr_cores, + (1 << die_offset), cs->nr_cores, eax, ebx, ecx, edx); break; } @@ -4399,12 +4400,14 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index= , uint32_t count, =20 switch (count) { case 0: - *eax =3D apicid_core_offset(cs->nr_cores, cs->nr_threads); + *eax =3D apicid_core_offset(env->nr_dies, + cs->nr_cores, cs->nr_threads); *ebx =3D cs->nr_threads; *ecx |=3D CPUID_TOPOLOGY_LEVEL_SMT; break; case 1: - *eax =3D apicid_pkg_offset(cs->nr_cores, cs->nr_threads); + *eax =3D apicid_pkg_offset(env->nr_dies, + cs->nr_cores, cs->nr_threads); *ebx =3D cs->nr_cores * cs->nr_threads; *ecx |=3D CPUID_TOPOLOGY_LEVEL_CORE; break; diff --git a/tests/test-x86-cpuid.c b/tests/test-x86-cpuid.c index ff225006e4..1942287f33 100644 --- a/tests/test-x86-cpuid.c +++ b/tests/test-x86-cpuid.c @@ -28,74 +28,80 @@ =20 static void test_topo_bits(void) { - /* simple tests for 1 thread per core, 1 core per socket */ - g_assert_cmpuint(apicid_smt_width(1, 1), =3D=3D, 0); - g_assert_cmpuint(apicid_core_width(1, 1), =3D=3D, 0); + /* simple tests for 1 thread per core, 1 core per die, 1 die per packa= ge */ + g_assert_cmpuint(apicid_smt_width(1, 1, 1), =3D=3D, 0); + g_assert_cmpuint(apicid_core_width(1, 1, 1), =3D=3D, 0); + g_assert_cmpuint(apicid_die_width(1, 1, 1), =3D=3D, 0); =20 - g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 0), =3D=3D, 0); - g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1), =3D=3D, 1); - g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 2), =3D=3D, 2); - g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 3), =3D=3D, 3); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 0), =3D=3D, 0); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 1), =3D=3D, 1); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 2), =3D=3D, 2); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 3), =3D=3D, 3); =20 =20 /* Test field width calculation for multiple values */ - g_assert_cmpuint(apicid_smt_width(1, 2), =3D=3D, 1); - g_assert_cmpuint(apicid_smt_width(1, 3), =3D=3D, 2); - g_assert_cmpuint(apicid_smt_width(1, 4), =3D=3D, 2); + g_assert_cmpuint(apicid_smt_width(1, 1, 2), =3D=3D, 1); + g_assert_cmpuint(apicid_smt_width(1, 1, 3), =3D=3D, 2); + g_assert_cmpuint(apicid_smt_width(1, 1, 4), =3D=3D, 2); =20 - g_assert_cmpuint(apicid_smt_width(1, 14), =3D=3D, 4); - g_assert_cmpuint(apicid_smt_width(1, 15), =3D=3D, 4); - g_assert_cmpuint(apicid_smt_width(1, 16), =3D=3D, 4); - g_assert_cmpuint(apicid_smt_width(1, 17), =3D=3D, 5); + g_assert_cmpuint(apicid_smt_width(1, 1, 14), =3D=3D, 4); + g_assert_cmpuint(apicid_smt_width(1, 1, 15), =3D=3D, 4); + g_assert_cmpuint(apicid_smt_width(1, 1, 16), =3D=3D, 4); + g_assert_cmpuint(apicid_smt_width(1, 1, 17), =3D=3D, 5); =20 =20 - g_assert_cmpuint(apicid_core_width(30, 2), =3D=3D, 5); - g_assert_cmpuint(apicid_core_width(31, 2), =3D=3D, 5); - g_assert_cmpuint(apicid_core_width(32, 2), =3D=3D, 5); - g_assert_cmpuint(apicid_core_width(33, 2), =3D=3D, 6); + g_assert_cmpuint(apicid_core_width(1, 30, 2), =3D=3D, 5); + g_assert_cmpuint(apicid_core_width(1, 31, 2), =3D=3D, 5); + g_assert_cmpuint(apicid_core_width(1, 32, 2), =3D=3D, 5); + g_assert_cmpuint(apicid_core_width(1, 33, 2), =3D=3D, 6); =20 + g_assert_cmpuint(apicid_die_width(1, 30, 2), =3D=3D, 0); + g_assert_cmpuint(apicid_die_width(2, 30, 2), =3D=3D, 1); + g_assert_cmpuint(apicid_die_width(3, 30, 2), =3D=3D, 2); + g_assert_cmpuint(apicid_die_width(4, 30, 2), =3D=3D, 2); =20 /* build a weird topology and see if IDs are calculated correctly */ =20 /* This will use 2 bits for thread ID and 3 bits for core ID */ - g_assert_cmpuint(apicid_smt_width(6, 3), =3D=3D, 2); - g_assert_cmpuint(apicid_core_width(6, 3), =3D=3D, 3); - g_assert_cmpuint(apicid_pkg_offset(6, 3), =3D=3D, 5); + g_assert_cmpuint(apicid_smt_width(1, 6, 3), =3D=3D, 2); + g_assert_cmpuint(apicid_core_offset(1, 6, 3), =3D=3D, 2); + g_assert_cmpuint(apicid_die_offset(1, 6, 3), =3D=3D, 5); + g_assert_cmpuint(apicid_pkg_offset(1, 6, 3), =3D=3D, 5); =20 - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 0), =3D=3D, 0); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 1), =3D=3D, 1); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 2), =3D=3D, 2); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 0), =3D=3D, 0); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1), =3D=3D, 1); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2), =3D=3D, 2); =20 - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 1 * 3 + 0), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1 * 3 + 0), =3D=3D, (1 << 2) | 0); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 1 * 3 + 1), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1 * 3 + 1), =3D=3D, (1 << 2) | 1); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 1 * 3 + 2), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1 * 3 + 2), =3D=3D, (1 << 2) | 2); =20 - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 2 * 3 + 0), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2 * 3 + 0), =3D=3D, (2 << 2) | 0); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 2 * 3 + 1), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2 * 3 + 1), =3D=3D, (2 << 2) | 1); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 2 * 3 + 2), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2 * 3 + 2), =3D=3D, (2 << 2) | 2); =20 - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 5 * 3 + 0), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 5 * 3 + 0), =3D=3D, (5 << 2) | 0); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 5 * 3 + 1), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 5 * 3 + 1), =3D=3D, (5 << 2) | 1); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 5 * 3 + 2), =3D=3D, + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 5 * 3 + 2), =3D=3D, (5 << 2) | 2); =20 - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 1 * 6 * 3 + 0 * 3 + 0),= =3D=3D, - (1 << 5)); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 1 * 6 * 3 + 1 * 3 + 1),= =3D=3D, - (1 << 5) | (1 << 2) | 1); - g_assert_cmpuint(x86_apicid_from_cpu_idx(6, 3, 3 * 6 * 3 + 5 * 3 + 2),= =3D=3D, - (3 << 5) | (5 << 2) | 2); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, + 1 * 6 * 3 + 0 * 3 + 0), =3D=3D, (1 << 5)); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, + 1 * 6 * 3 + 1 * 3 + 1), =3D=3D, (1 << 5) | (1 << 2) |= 1); + g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, + 3 * 6 * 3 + 5 * 3 + 2), =3D=3D, (3 << 5) | (5 << 2) |= 2); } =20 int main(int argc, char **argv) --=20 2.21.0 From nobody Mon Nov 10 17:35:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.intel.com ARC-Seal: i=1; a=rsa-sha256; t=1558429083; cv=none; d=zoho.com; s=zohoarc; b=LXVUdzKhYj8KlnlXS/FLPZNVyP5VG3C1w0sp1TTgUJN1HhRdnP3hXYP4SqYPmuM7kduPQKshEu/m8ByHpFv8woNFlXEPCBOpdnhe/+nqfKoVLNO2TAf39LzfdbRqCZgzrg2ub3ZcdcbJgO4zD2qBUZ6zCOpqOvM07uLzXKEiFx0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558429083; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=knoggEyCC9CpmDuG6SOYXx3W84rWPungAb2h6Iy+Qf4=; b=iRrOx3TagAS6L2AE92n579G8hQ3JN2ISQARMWD9+vnqzjD8lRTRwJ12ontEeapamBSH+l6ZyVIYSoJ+EnUKScGWZq+vf1ksXby6QhdZMm476Z6eqew5yjxk5Uzxgj2zcoz7YWUbyleKeXLMeyDgVTBspkAQW+U0xwB1ijgrTftA= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558429083150400.027638408956; Tue, 21 May 2019 01:58:03 -0700 (PDT) Received: from localhost ([127.0.0.1]:49397 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0au-00055x-EJ for importer@patchew.org; Tue, 21 May 2019 04:58:00 -0400 Received: from eggs.gnu.org ([209.51.188.92]:52010) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hT0WD-0001Nd-Sm for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hT0WC-0000fv-JQ for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:09 -0400 Received: from mga04.intel.com ([192.55.52.120]:1689) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hT0WC-0000dP-8W for qemu-devel@nongnu.org; Tue, 21 May 2019 04:53:08 -0400 Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 May 2019 01:53:07 -0700 Received: from clx-ap-likexu.sh.intel.com ([10.239.48.98]) by fmsmga007.fm.intel.com with ESMTP; 21 May 2019 01:53:05 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 From: Like Xu To: qemu-devel@nongnu.org Date: Tue, 21 May 2019 00:50:56 +0800 Message-Id: <20190520165056.175475-6-like.xu@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520165056.175475-1-like.xu@linux.intel.com> References: <20190520165056.175475-1-like.xu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.120 Subject: [Qemu-devel] [PATCH v2 5/5] target/i386: Add CPUID.1F generation support for multi-die PCMachine X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jones , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , Eduardo Habkost , Peter Crosthwaite , Marcelo Tosatti , "Dr . David Alan Gilbert" , Markus Armbruster , Brice Goglin , Paolo Bonzini , Igor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The CPUID.1F as Intel V2 Extended Topology Enumeration Leaf would be exposed if guests want to emulate multiple software-visible die within each package. Per Intel's SDM, the 0x1f is a superset of 0xb, thus they can be generated by almost same code as 0xb except die_offset setting. If the number of dies per package is less than 2, the qemu will not expose CPUID.1F regardless of whether the host supports CPUID.1F, and in any case, cpuid.0.eax would store the maximum input value for **guest** basic CPUID. If users do want to expose CPUID.1F by passing dies > 1 for simulation with= out host support, there will be a smp topology warning but it is not blocking. Signed-off-by: Like Xu --- target/i386/cpu.c | 37 +++++++++++++++++++++++++++++++++++++ target/i386/cpu.h | 4 ++++ target/i386/kvm.c | 30 ++++++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 3222bd3254..cd6c9933c3 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -4417,6 +4417,42 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,= uint32_t count, *ecx |=3D CPUID_TOPOLOGY_LEVEL_INVALID; } =20 + assert(!(*eax & ~0x1f)); + *ebx &=3D 0xffff; /* The count doesn't need to be reliable. */ + break; + case 0x1F: + /* V2 Extended Topology Enumeration Leaf */ + if (env->nr_dies < 2 || !cpu->enable_cpuid_0x1f) { + *eax =3D *ebx =3D *ecx =3D *edx =3D 0; + break; + } + + *ecx =3D count & 0xff; + *edx =3D cpu->apic_id; + switch (count) { + case 0: + *eax =3D apicid_core_offset(env->nr_dies, cs->nr_cores, + cs->nr_threads); + *ebx =3D cs->nr_threads; + *ecx |=3D CPUID_TOPOLOGY_LEVEL_SMT; + break; + case 1: + *eax =3D apicid_die_offset(env->nr_dies, cs->nr_cores, + cs->nr_threads); + *ebx =3D cs->nr_cores * cs->nr_threads; + *ecx |=3D CPUID_TOPOLOGY_LEVEL_CORE; + break; + case 2: + *eax =3D apicid_pkg_offset(env->nr_dies, cs->nr_cores, + cs->nr_threads); + *ebx =3D env->nr_dies * cs->nr_cores * cs->nr_threads; + *ecx |=3D CPUID_TOPOLOGY_LEVEL_DIE; + break; + default: + *eax =3D 0; + *ebx =3D 0; + *ecx |=3D CPUID_TOPOLOGY_LEVEL_INVALID; + } assert(!(*eax & ~0x1f)); *ebx &=3D 0xffff; /* The count doesn't need to be reliable. */ break; @@ -5864,6 +5900,7 @@ static Property x86_cpu_properties[] =3D { DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_leve= l, true), DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id), DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true), + DEFINE_PROP_BOOL("cpuid-0x1f", X86CPU, enable_cpuid_0x1f, true), DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false), DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true), DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index d5f2a60ff5..9b54c646e7 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -735,6 +735,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_TOPOLOGY_LEVEL_INVALID (0U << 8) #define CPUID_TOPOLOGY_LEVEL_SMT (1U << 8) #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8) +#define CPUID_TOPOLOGY_LEVEL_DIE (5U << 8) =20 /* MSR Feature Bits */ #define MSR_ARCH_CAP_RDCL_NO (1U << 0) @@ -1455,6 +1456,9 @@ struct X86CPU { /* Compatibility bits for old machine types: */ bool enable_cpuid_0xb; =20 + /* V2 Compatibility bits for old machine types: */ + bool enable_cpuid_0x1f; + /* Enable auto level-increase for all CPUID leaves */ bool full_cpuid_auto_level; =20 diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 3b29ce5c0d..d8b8bd5c9e 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -931,12 +931,12 @@ int kvm_arch_init_vcpu(CPUState *cs) struct kvm_cpuid_entry2 *c; uint32_t signature[3]; int kvm_base =3D KVM_CPUID_SIGNATURE; - int r; + int r, cpuid_0_entry, cpuid_min_level; Error *local_err =3D NULL; =20 memset(&cpuid_data, 0, sizeof(cpuid_data)); =20 - cpuid_i =3D 0; + cpuid_i =3D cpuid_0_entry =3D cpuid_min_level =3D 0; =20 r =3D kvm_arch_set_tsc_khz(cs); if (r < 0) { @@ -1050,6 +1050,11 @@ int kvm_arch_init_vcpu(CPUState *cs) =20 cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); =20 + if (limit < 0x1f && env->nr_dies > 1 && cpu->enable_cpuid_0x1f) { + limit =3D env->cpuid_level =3D env->cpuid_min_level =3D 0x1f; + warn_report("CPU topology: the CPUID.1F isn't supported on the hos= t."); + } + for (i =3D 0; i <=3D limit; i++) { if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { fprintf(stderr, "unsupported level value: 0x%x\n", limit); @@ -1081,6 +1086,10 @@ int kvm_arch_init_vcpu(CPUState *cs) } break; } + case 0x1f: + if (env->nr_dies < 2 || !cpu->enable_cpuid_0x1f) { + break; + } case 4: case 0xb: case 0xd: @@ -1088,6 +1097,11 @@ int kvm_arch_init_vcpu(CPUState *cs) if (i =3D=3D 0xd && j =3D=3D 64) { break; } + + if (i =3D=3D 0x1f && j =3D=3D 64) { + break; + } + c->function =3D i; c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; c->index =3D j; @@ -1099,6 +1113,9 @@ int kvm_arch_init_vcpu(CPUState *cs) if (i =3D=3D 0xb && !(c->ecx & 0xff00)) { break; } + if (i =3D=3D 0x1f && !(c->ecx & 0xff00)) { + break; + } if (i =3D=3D 0xd && c->eax =3D=3D 0) { continue; } @@ -1139,8 +1156,17 @@ int kvm_arch_init_vcpu(CPUState *cs) cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); break; } + + cpuid_0_entry =3D (i =3D=3D 0) ? (cpuid_i - 1) : cpuid_0_entry; + cpuid_min_level =3D + ((c->eax | c->ebx | c->ecx | c->edx | c->flags | c->index)= && + (i > cpuid_min_level)) ? i : cpuid_min_lev= el; } =20 + env->cpuid_level =3D env->cpuid_min_level =3D cpuid_min_level; + c =3D &cpuid_data.entries[cpuid_0_entry]; + cpu_x86_cpuid(env, 0, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + if (limit >=3D 0x0a) { uint32_t eax, edx; =20 --=20 2.21.0