From nobody Mon Nov 10 19:10:43 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