From nobody Wed Nov 19 00:16:28 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.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=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1613442196; cv=none; d=zohomail.com; s=zohoarc; b=EHmwGuuQ6jttDFq6PT1JMl5HU5m/t4JeBTOd6gu4vVJ6UMMj6CTaNbfdG8KJx7nfx+Srgl5uNCALFExVD1caivVfrVLiQxPc290KAcDceFW5oPNyMWnekqdal/9zh/VSGgZHMbWw6wJBzGvevTPeaFpsN79aUEOui6RO3OwZi6k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1613442196; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=kC0q/C3jn7KOq0ryQYWjjz1dXfbIJTm8UhLl6OXyfdQ=; b=K6rcjJcATO81lRqScdogkWruexoQlMXMRLnxFNRQIHvyKIDkXmLr7hgs/ClTN8sJ3xWVA4Oz3ym7HkKc3ITtobhzVPCH4y1BSKC8xOHGdEA6hpvp+7nBmax9FKqfzEklnMCNbLvU3/ne4z3wOq9WrsXhim4S5Q+f8b1Q0sDW4qc= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.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 1613442196473379.7212326173144; Mon, 15 Feb 2021 18:23:16 -0800 (PST) Received: from localhost ([::1]:49898 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lBq1D-0006b3-9X for importer@patchew.org; Mon, 15 Feb 2021 21:23:15 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45976) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lBptG-00061j-EL for qemu-devel@nongnu.org; Mon, 15 Feb 2021 21:15:02 -0500 Received: from mga17.intel.com ([192.55.52.151]:25640) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lBptD-0001b1-3U for qemu-devel@nongnu.org; Mon, 15 Feb 2021 21:15:02 -0500 Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2021 18:14:50 -0800 Received: from ls.sc.intel.com (HELO localhost) ([143.183.96.54]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2021 18:14:50 -0800 IronPort-SDR: shEW8dSIFH0gqdkNrE+wXG3VjSUhz3FHdEyvHHWh1sIOubV3C68/Y+UnBw4pgLCMCTB4+KoY4x 8be/oEEOosOw== X-IronPort-AV: E=McAfee;i="6000,8403,9896"; a="162558750" X-IronPort-AV: E=Sophos;i="5.81,182,1610438400"; d="scan'208";a="162558750" IronPort-SDR: FiEC2/fGZjoAYFutqHwRCGeWNKn4qgtjipuWv5MvsbHi1R6hk9SWSZqZdHev5sZiSIlGj4m6Mh d7RHnAyXGmtQ== X-IronPort-AV: E=Sophos;i="5.81,182,1610438400"; d="scan'208";a="591705392" From: Isaku Yamahata To: qemu-devel@nongnu.org, pbonzini@redhat.com, alistair@alistair23.me, ehabkost@redhat.com, marcel.apfelbaum@gmail.com, mst@redhat.com, cohuck@redhat.com, mtosatti@redhat.com, xiaoyao.li@intel.com, seanjc@google.com Subject: [RFC PATCH 04/23] i386/kvm: Move architectural CPUID leaf generation to separarte helper Date: Mon, 15 Feb 2021 18:13:00 -0800 Message-Id: <66dbf12944f81c25e3a0d3d7afac159858cb78bd.1613188118.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=192.55.52.151; envelope-from=isaku.yamahata@intel.com; helo=mga17.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: isaku.yamahata@intel.com, Sean Christopherson , isaku.yamahata@gmail.com, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Sean Christopherson Move the architectural (for lack of a better term) CPUID leaf generation to a separate helper so that the generation code can be reused by TDX, which needs to generate a canonical VM-scoped configuration. Signed-off-by: Sean Christopherson --- target/i386/kvm/kvm.c | 170 +++++++++++++++++++------------------ target/i386/kvm/kvm_i386.h | 4 + 2 files changed, 93 insertions(+), 81 deletions(-) diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 8a04cf1337..bb241d8aa1 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -1461,82 +1461,11 @@ static int hyperv_init_vcpu(X86CPU *cpu) =20 static Error *invtsc_mig_blocker; =20 -#define KVM_MAX_CPUID_ENTRIES 100 - -int kvm_arch_init_vcpu(CPUState *cs) +uint32_t kvm_x86_arch_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *ent= ries, + uint32_t cpuid_i) { - struct { - struct kvm_cpuid2 cpuid; - struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES]; - } cpuid_data; - /* - * The kernel defines these structs with padding fields so there - * should be no extra padding in our cpuid_data struct. - */ - QEMU_BUILD_BUG_ON(sizeof(cpuid_data) !=3D - sizeof(struct kvm_cpuid2) + - sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTR= IES); - - X86CPU *cpu =3D X86_CPU(cs); - CPUX86State *env =3D &cpu->env; - uint32_t limit, i, j, cpuid_i; - uint32_t unused; + uint32_t limit, i, j, unused; struct kvm_cpuid_entry2 *c; - uint32_t signature[3]; - int kvm_base =3D KVM_CPUID_SIGNATURE; - int max_nested_state_len; - int r; - Error *local_err =3D NULL; - - memset(&cpuid_data, 0, sizeof(cpuid_data)); - - cpuid_i =3D 0; - - r =3D kvm_arch_set_tsc_khz(cs); - if (r < 0) { - return r; - } - - /* vcpu's TSC frequency is either specified by user, or following - * the value used by KVM if the former is not present. In the - * latter case, we query it from KVM and record in env->tsc_khz, - * so that vcpu's TSC frequency can be migrated later via this field. - */ - if (!env->tsc_khz) { - r =3D kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ? - kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) : - -ENOTSUP; - if (r > 0) { - env->tsc_khz =3D r; - } - } - - env->apic_bus_freq =3D KVM_APIC_BUS_FREQUENCY; - - /* Paravirtualization CPUIDs */ - r =3D hyperv_handle_properties(cs, cpuid_data.entries); - if (r < 0) { - return r; - } else if (r > 0) { - cpuid_i =3D r; - kvm_base =3D KVM_CPUID_SIGNATURE_NEXT; - has_msr_hv_hypercall =3D true; - } - - if (cpu->expose_kvm) { - memcpy(signature, "KVMKVMKVM\0\0\0", 12); - c =3D &cpuid_data.entries[cpuid_i++]; - c->function =3D KVM_CPUID_SIGNATURE | kvm_base; - c->eax =3D KVM_CPUID_FEATURES | kvm_base; - c->ebx =3D signature[0]; - c->ecx =3D signature[1]; - c->edx =3D signature[2]; - - c =3D &cpuid_data.entries[cpuid_i++]; - c->function =3D KVM_CPUID_FEATURES | kvm_base; - c->eax =3D env->features[FEAT_KVM]; - c->edx =3D env->features[FEAT_KVM_HINTS]; - } =20 cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); =20 @@ -1545,7 +1474,7 @@ int kvm_arch_init_vcpu(CPUState *cs) fprintf(stderr, "unsupported level value: 0x%x\n", limit); abort(); } - c =3D &cpuid_data.entries[cpuid_i++]; + c =3D &entries[cpuid_i++]; =20 switch (i) { case 2: { @@ -1564,7 +1493,7 @@ int kvm_arch_init_vcpu(CPUState *cs) "cpuid(eax:2):eax & 0xf =3D 0x%x\n", times); abort(); } - c =3D &cpuid_data.entries[cpuid_i++]; + c =3D &entries[cpuid_i++]; c->function =3D i; c->flags =3D KVM_CPUID_FLAG_STATEFUL_FUNC; cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->ed= x); @@ -1610,7 +1539,7 @@ int kvm_arch_init_vcpu(CPUState *cs) "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); abort(); } - c =3D &cpuid_data.entries[cpuid_i++]; + c =3D &entries[cpuid_i++]; } break; case 0x7: @@ -1629,7 +1558,7 @@ int kvm_arch_init_vcpu(CPUState *cs) "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); abort(); } - c =3D &cpuid_data.entries[cpuid_i++]; + c =3D &entries[cpuid_i++]; c->function =3D i; c->index =3D j; c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; @@ -1686,7 +1615,7 @@ int kvm_arch_init_vcpu(CPUState *cs) fprintf(stderr, "unsupported xlevel value: 0x%x\n", limit); abort(); } - c =3D &cpuid_data.entries[cpuid_i++]; + c =3D &entries[cpuid_i++]; =20 switch (i) { case 0x8000001d: @@ -1705,7 +1634,7 @@ int kvm_arch_init_vcpu(CPUState *cs) "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); abort(); } - c =3D &cpuid_data.entries[cpuid_i++]; + c =3D &entries[cpuid_i++]; } break; default: @@ -1732,7 +1661,7 @@ int kvm_arch_init_vcpu(CPUState *cs) fprintf(stderr, "unsupported xlevel2 value: 0x%x\n", limit= ); abort(); } - c =3D &cpuid_data.entries[cpuid_i++]; + c =3D &entries[cpuid_i++]; =20 c->function =3D i; c->flags =3D 0; @@ -1740,6 +1669,85 @@ int kvm_arch_init_vcpu(CPUState *cs) } } =20 + return cpuid_i; +} + +int kvm_arch_init_vcpu(CPUState *cs) +{ + struct { + struct kvm_cpuid2 cpuid; + struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES]; + } cpuid_data; + /* + * The kernel defines these structs with padding fields so there + * should be no extra padding in our cpuid_data struct. + */ + QEMU_BUILD_BUG_ON(sizeof(cpuid_data) !=3D + sizeof(struct kvm_cpuid2) + + sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTR= IES); + + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + uint32_t cpuid_i; + struct kvm_cpuid_entry2 *c; + uint32_t signature[3]; + int kvm_base =3D KVM_CPUID_SIGNATURE; + int max_nested_state_len; + int r; + Error *local_err =3D NULL; + + memset(&cpuid_data, 0, sizeof(cpuid_data)); + + cpuid_i =3D 0; + + r =3D kvm_arch_set_tsc_khz(cs); + if (r < 0) { + return r; + } + + /* + * vcpu's TSC frequency is either specified by user, or following + * the value used by KVM if the former is not present. In the + * latter case, we query it from KVM and record in env->tsc_khz, + * so that vcpu's TSC frequency can be migrated later via this field. + */ + if (!env->tsc_khz) { + r =3D kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ? + kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) : + -ENOTSUP; + if (r > 0) { + env->tsc_khz =3D r; + } + } + + env->apic_bus_freq =3D KVM_APIC_BUS_FREQUENCY; + + /* Paravirtualization CPUIDs */ + r =3D hyperv_handle_properties(cs, cpuid_data.entries); + if (r < 0) { + return r; + } else if (r > 0) { + cpuid_i =3D r; + kvm_base =3D KVM_CPUID_SIGNATURE_NEXT; + has_msr_hv_hypercall =3D true; + } + + if (cpu->expose_kvm) { + memcpy(signature, "KVMKVMKVM\0\0\0", 12); + c =3D &cpuid_data.entries[cpuid_i++]; + c->function =3D KVM_CPUID_SIGNATURE | kvm_base; + c->eax =3D KVM_CPUID_FEATURES | kvm_base; + c->ebx =3D signature[0]; + c->ecx =3D signature[1]; + c->edx =3D signature[2]; + + c =3D &cpuid_data.entries[cpuid_i++]; + c->function =3D KVM_CPUID_FEATURES | kvm_base; + c->eax =3D env->features[FEAT_KVM]; + c->edx =3D env->features[FEAT_KVM_HINTS]; + } + + cpuid_i =3D kvm_x86_arch_cpuid(env, cpuid_data.entries, cpuid_i); cpuid_data.cpuid.nent =3D cpuid_i; =20 if (((env->cpuid_version >> 8)&0xF) >=3D 6 diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h index dc72508389..c9a92578b1 100644 --- a/target/i386/kvm/kvm_i386.h +++ b/target/i386/kvm/kvm_i386.h @@ -24,6 +24,10 @@ #define kvm_ioapic_in_kernel() \ (kvm_irqchip_in_kernel() && !kvm_irqchip_is_split()) =20 +#define KVM_MAX_CPUID_ENTRIES 100 +uint32_t kvm_x86_arch_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *ent= ries, + uint32_t cpuid_i); + #else =20 #define kvm_pit_in_kernel() 0 --=20 2.17.1