From nobody Tue Feb 10 01:50:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1711131201; cv=none; d=zohomail.com; s=zohoarc; b=h3Rg3cUtObkOmskWAYUdBrVA58M0zC/veu235Lxj56MjNmvpqUMtYhFN1yuK9N9BIh/kdQSQmUA5W9IUGtJZR3ZUsMmH9+XjfBTTVB6N+bC5GblAv40DSNAHvB5vBFbBWJRgT7hgZnNNMejsBT62z8fu7t/jo/nS4gwML980/NI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1711131201; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=PE8fCe2s2Jw3S6PeFQU1PRfeQvgplgZHE1QIHN3l5mQ=; b=ELg5OLJvDvgXzZ/EilLPMwc4uB8ARIaGp7V9dRSKc2af85jZw6pdCjAvKgs+OAur0KXwgQ7XfH2oOXQ+fhRAxZxkJduupQYNgXWnUYtWvkRKMK49e8x40UN70e9ACzhYHG9HuvebhJlB82P0aDj4x99PbjJ6xTEe55lKfZyiaAA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1711131201551595.2150323553616; Fri, 22 Mar 2024 11:13:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rnjO5-00013H-2f; Fri, 22 Mar 2024 14:13:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rnjNt-0000rG-1d for qemu-devel@nongnu.org; Fri, 22 Mar 2024 14:12:53 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rnjNj-00079G-3D for qemu-devel@nongnu.org; Fri, 22 Mar 2024 14:12:51 -0400 Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-295-z3wliKYoP2SGHIBVUliqMQ-1; Fri, 22 Mar 2024 14:12:41 -0400 Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-a45acc7f07cso138353966b.2 for ; Fri, 22 Mar 2024 11:12:40 -0700 (PDT) Received: from [192.168.10.118] ([151.95.49.219]) by smtp.gmail.com with ESMTPSA id jt7-20020a170906dfc700b00a4635a21ff0sm79529ejc.38.2024.03.22.11.12.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Mar 2024 11:12:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711131162; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PE8fCe2s2Jw3S6PeFQU1PRfeQvgplgZHE1QIHN3l5mQ=; b=QQ7N0tLnv/cpJT36QnBHtqYVUTiCSVl9dDZ/fZwGXsThW8u/BfSrqm2ctNG1xNBREpH6HV 2Gl0heU/2DDzZldsINnCrZ5J0wj1XDaoflStxyMjUVFktrRQbcJIKSYwlDLnFXLjQpe2Kl EEZ0jkWRamkBV4f/61Eix6jlhzyWoIg= X-MC-Unique: z3wliKYoP2SGHIBVUliqMQ-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711131159; x=1711735959; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PE8fCe2s2Jw3S6PeFQU1PRfeQvgplgZHE1QIHN3l5mQ=; b=GM19ruH3TtQjRSS7+vlHs/ci2hkY4UkX0zm3iquaf6DFU09ioTk2nqEnYmZjhV3qrG Wha14gmBmg3oSvcjtFDaosKX+gDtZjhMdelN6MtgHO3u5cig3C8t06Na6sg/A/8jiXqu 6KpNIiXRdl53K5mdjkzrhaeQEfB7MsYXyPNx7E1y4f3V1lTk3xj2kuXv9ZGT2zE6v+KJ ywSMFchSsVRHxGuikR9XiYejLKdj7rt8LaoTOoqXpQIb+jwmhaU1RcGUdtfUT3t0To/l 7mNbgDx1FhZiUbAfqOOsWqqMx13TkX+h5YsOg+xP6zwp6xJaOuqtSrA4J9reWf+tuLQN Yhhw== X-Gm-Message-State: AOJu0YzhT9eSMWrJMKEwmKdB8nqRaMT48uTCVQb1XZuJRI4Yu84HA5iO K+3hdAKB2IUbJOAendbaOFCmno67fhMEmAl8E2hBoqfxdOkPzfSTEQfvLn3NztmmTEmPCmI5E9D uvnrXKs3cYYucTs0G3W/PHbQy1KKVV6U5N8JUzXqoaWT8Ub4zh48HirF5JFDCFcsvjptz6QgbQK LNwR2X4k6USk4uNZ8bdmIr2x9Ks1fspdV+P3O2 X-Received: by 2002:a17:906:a15a:b0:a47:1c57:5125 with SMTP id bu26-20020a170906a15a00b00a471c575125mr381229ejb.41.1711131158662; Fri, 22 Mar 2024 11:12:38 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF9Ot1HK5cMAADoI+FuvlDHwemc9cFbQo8KrrAVE1iMNGeyLmqI/6n2xYaiOUIWMEffm3QAmA== X-Received: by 2002:a17:906:a15a:b0:a47:1c57:5125 with SMTP id bu26-20020a170906a15a00b00a471c575125mr381211ejb.41.1711131158258; Fri, 22 Mar 2024 11:12:38 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: xiaoyao.li@intel.com, michael.roth@amd.com, david@redhat.com Subject: [PATCH 26/26] i386/kvm: Move architectural CPUID leaf generation to separate helper Date: Fri, 22 Mar 2024 19:11:16 +0100 Message-ID: <20240322181116.1228416-27-pbonzini@redhat.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240322181116.1228416-1-pbonzini@redhat.com> References: <20240322181116.1228416-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.222, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1711131203243100003 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. For now this is just a cleanup, so keep the function static. Signed-off-by: Sean Christopherson Signed-off-by: Xiaoyao Li Message-ID: <20240229063726.610065-23-xiaoyao.li@intel.com> [Unify error reporting, rename function. - Paolo] Signed-off-by: Paolo Bonzini Reviewed-by: Xiaoyao Li --- target/i386/kvm/kvm.c | 446 +++++++++++++++++++++--------------------- 1 file changed, 224 insertions(+), 222 deletions(-) diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 2577e345502..eab6261e1f5 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -1752,6 +1752,228 @@ static void kvm_init_nested_state(CPUX86State *env) } } =20 +static uint32_t kvm_x86_build_cpuid(CPUX86State *env, + struct kvm_cpuid_entry2 *entries, + uint32_t cpuid_i) +{ + uint32_t limit, i, j; + uint32_t unused; + struct kvm_cpuid_entry2 *c; + + cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); + + for (i =3D 0; i <=3D limit; i++) { + j =3D 0; + if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { + goto full; + } + c =3D &entries[cpuid_i++]; + switch (i) { + case 2: { + /* Keep reading function 2 till all the input is received */ + int times; + + c->function =3D i; + c->flags =3D KVM_CPUID_FLAG_STATEFUL_FUNC | + KVM_CPUID_FLAG_STATE_READ_NEXT; + cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + times =3D c->eax & 0xff; + + for (j =3D 1; j < times; ++j) { + if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { + goto full; + } + 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); + } + break; + } + case 0x1f: + if (env->nr_dies < 2) { + cpuid_i--; + break; + } + /* fallthrough */ + case 4: + case 0xb: + case 0xd: + for (j =3D 0; ; j++) { + if (i =3D=3D 0xd && j =3D=3D 64) { + break; + } + + c->function =3D i; + c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + c->index =3D j; + cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->ed= x); + + if (i =3D=3D 4 && c->eax =3D=3D 0) { + break; + } + 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; + } + if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { + goto full; + } + c =3D &entries[cpuid_i++]; + } + break; + case 0x12: + for (j =3D 0; ; j++) { + c->function =3D i; + c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + c->index =3D j; + cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->ed= x); + + if (j > 1 && (c->eax & 0xf) !=3D 1) { + break; + } + + if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { + goto full; + } + c =3D &entries[cpuid_i++]; + } + break; + case 0x7: + case 0x14: + case 0x1d: + case 0x1e: { + uint32_t times; + + c->function =3D i; + c->index =3D 0; + c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + times =3D c->eax; + + for (j =3D 1; j <=3D times; ++j) { + if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { + goto full; + } + c =3D &entries[cpuid_i++]; + c->function =3D i; + c->index =3D j; + c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->ed= x); + } + break; + } + default: + c->function =3D i; + c->flags =3D 0; + cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + if (!c->eax && !c->ebx && !c->ecx && !c->edx) { + /* + * KVM already returns all zeroes if a CPUID entry is miss= ing, + * so we can omit it and avoid hitting KVM's 80-entry limi= t. + */ + cpuid_i--; + } + break; + } + } + + if (limit >=3D 0x0a) { + uint32_t eax, edx; + + cpu_x86_cpuid(env, 0x0a, 0, &eax, &unused, &unused, &edx); + + has_architectural_pmu_version =3D eax & 0xff; + if (has_architectural_pmu_version > 0) { + num_architectural_pmu_gp_counters =3D (eax & 0xff00) >> 8; + + /* Shouldn't be more than 32, since that's the number of bits + * available in EBX to tell us _which_ counters are available. + * Play it safe. + */ + if (num_architectural_pmu_gp_counters > MAX_GP_COUNTERS) { + num_architectural_pmu_gp_counters =3D MAX_GP_COUNTERS; + } + + if (has_architectural_pmu_version > 1) { + num_architectural_pmu_fixed_counters =3D edx & 0x1f; + + if (num_architectural_pmu_fixed_counters > MAX_FIXED_COUNT= ERS) { + num_architectural_pmu_fixed_counters =3D MAX_FIXED_COU= NTERS; + } + } + } + } + + cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused); + + for (i =3D 0x80000000; i <=3D limit; i++) { + j =3D 0; + c =3D &entries[cpuid_i++]; + + switch (i) { + case 0x8000001d: + /* Query for all AMD cache information leaves */ + for (j =3D 0; ; j++) { + c->function =3D i; + c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + c->index =3D j; + cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->ed= x); + + if (c->eax =3D=3D 0) { + break; + } + if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { + goto full; + } + c =3D &entries[cpuid_i++]; + } + break; + default: + c->function =3D i; + c->flags =3D 0; + cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + if (!c->eax && !c->ebx && !c->ecx && !c->edx) { + /* + * KVM already returns all zeroes if a CPUID entry is miss= ing, + * so we can omit it and avoid hitting KVM's 80-entry limi= t. + */ + cpuid_i--; + } + break; + } + } + + /* Call Centaur's CPUID instructions they are supported. */ + if (env->cpuid_xlevel2 > 0) { + cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unuse= d); + + for (i =3D 0xC0000000; i <=3D limit; i++) { + j =3D 0; + if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { + goto full; + } + c =3D &entries[cpuid_i++]; + + c->function =3D i; + c->flags =3D 0; + cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + } + } + + return cpuid_i; + +full: + fprintf(stderr, "cpuid_data is full, no space for " + "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); + abort(); +} + int kvm_arch_init_vcpu(CPUState *cs) { struct { @@ -1768,8 +1990,7 @@ int kvm_arch_init_vcpu(CPUState *cs) =20 X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; - uint32_t limit, i, j, cpuid_i; - uint32_t unused; + uint32_t cpuid_i; struct kvm_cpuid_entry2 *c; uint32_t signature[3]; int kvm_base =3D KVM_CPUID_SIGNATURE; @@ -1922,8 +2143,6 @@ int kvm_arch_init_vcpu(CPUState *cs) c->edx =3D env->features[FEAT_KVM_HINTS]; } =20 - cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); - if (cpu->kvm_pv_enforce_cpuid) { r =3D kvm_vcpu_enable_cap(cs, KVM_CAP_ENFORCE_PV_FEATURE_CPUID, 0,= 1); if (r < 0) { @@ -1934,224 +2153,7 @@ int kvm_arch_init_vcpu(CPUState *cs) } } =20 - 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); - abort(); - } - c =3D &cpuid_data.entries[cpuid_i++]; - - switch (i) { - case 2: { - /* Keep reading function 2 till all the input is received */ - int times; - - c->function =3D i; - c->flags =3D KVM_CPUID_FLAG_STATEFUL_FUNC | - KVM_CPUID_FLAG_STATE_READ_NEXT; - cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); - times =3D c->eax & 0xff; - - for (j =3D 1; j < times; ++j) { - if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { - fprintf(stderr, "cpuid_data is full, no space for " - "cpuid(eax:2):eax & 0xf =3D 0x%x\n", times); - abort(); - } - c =3D &cpuid_data.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); - } - break; - } - case 0x1f: - if (env->nr_dies < 2) { - cpuid_i--; - break; - } - /* fallthrough */ - case 4: - case 0xb: - case 0xd: - for (j =3D 0; ; j++) { - if (i =3D=3D 0xd && j =3D=3D 64) { - break; - } - - c->function =3D i; - c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; - c->index =3D j; - cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->ed= x); - - if (i =3D=3D 4 && c->eax =3D=3D 0) { - break; - } - 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; - } - if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { - fprintf(stderr, "cpuid_data is full, no space for " - "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); - abort(); - } - c =3D &cpuid_data.entries[cpuid_i++]; - } - break; - case 0x12: - for (j =3D 0; ; j++) { - c->function =3D i; - c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; - c->index =3D j; - cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->ed= x); - - if (j > 1 && (c->eax & 0xf) !=3D 1) { - break; - } - - if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { - fprintf(stderr, "cpuid_data is full, no space for " - "cpuid(eax:0x12,ecx:0x%x)\n", j); - abort(); - } - c =3D &cpuid_data.entries[cpuid_i++]; - } - break; - case 0x7: - case 0x14: - case 0x1d: - case 0x1e: { - uint32_t times; - - c->function =3D i; - c->index =3D 0; - c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; - cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); - times =3D c->eax; - - for (j =3D 1; j <=3D times; ++j) { - if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { - fprintf(stderr, "cpuid_data is full, no space for " - "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); - abort(); - } - c =3D &cpuid_data.entries[cpuid_i++]; - c->function =3D i; - c->index =3D j; - c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; - cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->ed= x); - } - break; - } - default: - c->function =3D i; - c->flags =3D 0; - cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); - if (!c->eax && !c->ebx && !c->ecx && !c->edx) { - /* - * KVM already returns all zeroes if a CPUID entry is miss= ing, - * so we can omit it and avoid hitting KVM's 80-entry limi= t. - */ - cpuid_i--; - } - break; - } - } - - if (limit >=3D 0x0a) { - uint32_t eax, edx; - - cpu_x86_cpuid(env, 0x0a, 0, &eax, &unused, &unused, &edx); - - has_architectural_pmu_version =3D eax & 0xff; - if (has_architectural_pmu_version > 0) { - num_architectural_pmu_gp_counters =3D (eax & 0xff00) >> 8; - - /* Shouldn't be more than 32, since that's the number of bits - * available in EBX to tell us _which_ counters are available. - * Play it safe. - */ - if (num_architectural_pmu_gp_counters > MAX_GP_COUNTERS) { - num_architectural_pmu_gp_counters =3D MAX_GP_COUNTERS; - } - - if (has_architectural_pmu_version > 1) { - num_architectural_pmu_fixed_counters =3D edx & 0x1f; - - if (num_architectural_pmu_fixed_counters > MAX_FIXED_COUNT= ERS) { - num_architectural_pmu_fixed_counters =3D MAX_FIXED_COU= NTERS; - } - } - } - } - - cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused); - - for (i =3D 0x80000000; i <=3D limit; i++) { - if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { - fprintf(stderr, "unsupported xlevel value: 0x%x\n", limit); - abort(); - } - c =3D &cpuid_data.entries[cpuid_i++]; - - switch (i) { - case 0x8000001d: - /* Query for all AMD cache information leaves */ - for (j =3D 0; ; j++) { - c->function =3D i; - c->flags =3D KVM_CPUID_FLAG_SIGNIFCANT_INDEX; - c->index =3D j; - cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->ed= x); - - if (c->eax =3D=3D 0) { - break; - } - if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { - fprintf(stderr, "cpuid_data is full, no space for " - "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); - abort(); - } - c =3D &cpuid_data.entries[cpuid_i++]; - } - break; - default: - c->function =3D i; - c->flags =3D 0; - cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); - if (!c->eax && !c->ebx && !c->ecx && !c->edx) { - /* - * KVM already returns all zeroes if a CPUID entry is miss= ing, - * so we can omit it and avoid hitting KVM's 80-entry limi= t. - */ - cpuid_i--; - } - break; - } - } - - /* Call Centaur's CPUID instructions they are supported. */ - if (env->cpuid_xlevel2 > 0) { - cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unuse= d); - - for (i =3D 0xC0000000; i <=3D limit; i++) { - if (cpuid_i =3D=3D KVM_MAX_CPUID_ENTRIES) { - fprintf(stderr, "unsupported xlevel2 value: 0x%x\n", limit= ); - abort(); - } - c =3D &cpuid_data.entries[cpuid_i++]; - - c->function =3D i; - c->flags =3D 0; - cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); - } - } - + cpuid_i =3D kvm_x86_build_cpuid(env, cpuid_data.entries, cpuid_i); cpuid_data.cpuid.nent =3D cpuid_i; =20 if (((env->cpuid_version >> 8)&0xF) >=3D 6 --=20 2.44.0