qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Xiaoyao Li <xiaoyao.li@intel.com>, Zhao Liu <zhao1.liu@intel.com>
Subject: [PULL 56/77] i386/tdx: Implement adjust_cpuid_features() for TDX
Date: Fri, 30 May 2025 09:12:26 +0200	[thread overview]
Message-ID: <20250530071250.2050910-57-pbonzini@redhat.com> (raw)
In-Reply-To: <20250530071250.2050910-1-pbonzini@redhat.com>

From: Xiaoyao Li <xiaoyao.li@intel.com>

Maintain a TDX specific supported CPUID set, and use it to mask the
common supported CPUID value of KVM. It can avoid newly added supported
features (reported via KVM_GET_SUPPORTED_CPUID) for common VMs being
falsely reported as supported for TDX.

As the first step, initialize the TDX supported CPUID set with all the
configurable CPUID bits. It's not complete because there are other CPUID
bits are supported for TDX but not reported as directly configurable.
E.g. the XFAM related bits, attribute related bits and fixed-1 bits.
They will be handled in the future.

Also, what matters are the CPUID bits related to QEMU's feature word.
Only mask the CPUID leafs which are feature word leaf.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20250508150002.689633-45-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.h          |  1 +
 target/i386/kvm/kvm_i386.h |  1 +
 target/i386/cpu.c          | 16 ++++++++++++++++
 target/i386/kvm/kvm.c      |  2 +-
 target/i386/kvm/tdx.c      | 34 ++++++++++++++++++++++++++++++++++
 5 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ad0e3d8cdd0..7ffcf91b014 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2502,6 +2502,7 @@ void cpu_set_apic_feature(CPUX86State *env);
 void host_cpuid(uint32_t function, uint32_t count,
                 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
 bool cpu_has_x2apic_feature(CPUX86State *env);
+bool is_feature_word_cpuid(uint32_t feature, uint32_t index, int reg);
 
 static inline bool x86_has_cpuid_0x1f(X86CPU *cpu)
 {
diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h
index dc696cb7238..484a1de84d5 100644
--- a/target/i386/kvm/kvm_i386.h
+++ b/target/i386/kvm/kvm_i386.h
@@ -62,6 +62,7 @@ void kvm_update_msi_routes_all(void *private, bool global,
 struct kvm_cpuid_entry2 *cpuid_find_entry(struct kvm_cpuid2 *cpuid,
                                           uint32_t function,
                                           uint32_t index);
+uint32_t cpuid_entry_get_reg(struct kvm_cpuid_entry2 *entry, int reg);
 uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *entries,
                              uint32_t cpuid_i);
 #endif /* CONFIG_KVM */
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 6a97d7549ec..5aacb62f081 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1678,6 +1678,22 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
     },
 };
 
+bool is_feature_word_cpuid(uint32_t feature, uint32_t index, int reg)
+{
+    FeatureWordInfo *wi;
+    FeatureWord w;
+
+    for (w = 0; w < FEATURE_WORDS; w++) {
+        wi = &feature_word_info[w];
+        if (wi->type == CPUID_FEATURE_WORD && wi->cpuid.eax == feature &&
+            (!wi->cpuid.needs_ecx || wi->cpuid.ecx == index) &&
+            wi->cpuid.reg == reg) {
+            return true;
+        }
+    }
+    return false;
+}
+
 typedef struct FeatureMask {
     FeatureWord index;
     uint64_t mask;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 0d474634312..cd87f5502a3 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -394,7 +394,7 @@ static bool host_tsx_broken(void)
 
 /* Returns the value for a specific register on the cpuid entry
  */
-static uint32_t cpuid_entry_get_reg(struct kvm_cpuid_entry2 *entry, int reg)
+uint32_t cpuid_entry_get_reg(struct kvm_cpuid_entry2 *entry, int reg)
 {
     uint32_t ret = 0;
     switch (reg) {
diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
index 68ed3b9f987..e3b7ad6d146 100644
--- a/target/i386/kvm/tdx.c
+++ b/target/i386/kvm/tdx.c
@@ -45,6 +45,7 @@
 static TdxGuest *tdx_guest;
 
 static struct kvm_tdx_capabilities *tdx_caps;
+static struct kvm_cpuid2 *tdx_supported_cpuid;
 
 /* Valid after kvm_arch_init()->confidential_guest_kvm_init()->tdx_kvm_init() */
 bool is_tdx_vm(void)
@@ -366,6 +367,20 @@ static Notifier tdx_machine_done_notify = {
     .notify = tdx_finalize_vm,
 };
 
+static void tdx_setup_supported_cpuid(void)
+{
+    if (tdx_supported_cpuid) {
+        return;
+    }
+
+    tdx_supported_cpuid = g_malloc0(sizeof(*tdx_supported_cpuid) +
+                    KVM_MAX_CPUID_ENTRIES * sizeof(struct kvm_cpuid_entry2));
+
+    memcpy(tdx_supported_cpuid->entries, tdx_caps->cpuid.entries,
+           tdx_caps->cpuid.nent * sizeof(struct kvm_cpuid_entry2));
+    tdx_supported_cpuid->nent = tdx_caps->cpuid.nent;
+}
+
 static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
 {
     MachineState *ms = MACHINE(qdev_get_machine());
@@ -403,6 +418,8 @@ static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
         }
     }
 
+    tdx_setup_supported_cpuid();
+
     /* TDX relies on KVM_HC_MAP_GPA_RANGE to handle TDG.VP.VMCALL<MapGPA> */
     if (!kvm_enable_hypercall(BIT_ULL(KVM_HC_MAP_GPA_RANGE))) {
         return -EOPNOTSUPP;
@@ -440,6 +457,22 @@ static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu)
     x86cpu->enable_cpuid_0x1f = true;
 }
 
+static uint32_t tdx_adjust_cpuid_features(X86ConfidentialGuest *cg,
+                                          uint32_t feature, uint32_t index,
+                                          int reg, uint32_t value)
+{
+    struct kvm_cpuid_entry2 *e;
+
+    if (is_feature_word_cpuid(feature, index, reg)) {
+        e = cpuid_find_entry(tdx_supported_cpuid, feature, index);
+        if (e) {
+            value &= cpuid_entry_get_reg(e, reg);
+        }
+    }
+
+    return value;
+}
+
 static int tdx_validate_attributes(TdxGuest *tdx, Error **errp)
 {
     if ((tdx->attributes & ~tdx_caps->supported_attrs)) {
@@ -834,4 +867,5 @@ static void tdx_guest_class_init(ObjectClass *oc, const void *data)
     klass->kvm_init = tdx_kvm_init;
     x86_klass->kvm_type = tdx_kvm_type;
     x86_klass->cpu_instance_init = tdx_cpu_instance_init;
+    x86_klass->adjust_cpuid_features = tdx_adjust_cpuid_features;
 }
-- 
2.49.0



  parent reply	other threads:[~2025-05-30  7:26 UTC|newest]

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-30  7:11 [PULL 00/77] i386, build system changes for 2025-05-30 Paolo Bonzini
2025-05-30  7:11 ` [PULL 01/77] meson: build target libraries with common dependencies Paolo Bonzini
2025-05-30  7:11 ` [PULL 02/77] hw/arm: remove explicit dependencies listed Paolo Bonzini
2025-06-02 13:59   ` Cédric Le Goater
2025-06-02 18:39     ` Pierrick Bouvier
2025-06-02 20:53       ` Nabih Estefan
2025-06-02 21:11         ` Cédric Le Goater
2025-06-02 22:37           ` Pierrick Bouvier
2025-06-02 23:40             ` Pierrick Bouvier
2025-05-30  7:11 ` [PULL 03/77] target/arm: " Paolo Bonzini
2025-05-30  7:11 ` [PULL 04/77] meson: apply target config for picking files from lib{system, user} Paolo Bonzini
2025-05-30  7:11 ` [PULL 05/77] meson: merge lib{system, user}_ss with {system, user}_ss Paolo Bonzini
2025-05-30  7:11 ` [PULL 06/77] meson: remove lib{system, user}_ss aliases Paolo Bonzini
2025-05-30  7:11 ` [PULL 07/77] meson: merge hw_common_arch in target_common_system_arch Paolo Bonzini
2025-05-30  7:11 ` [PULL 08/77] hw/timer/hpet: Reorganize register decoding Paolo Bonzini
2025-05-30  7:11 ` [PULL 09/77] rust: Fix Zhao's email address Paolo Bonzini
2025-05-30  7:11 ` [PULL 10/77] rust: Fix the typos in doc Paolo Bonzini
2025-05-30  7:11 ` [PULL 11/77] rust: hpet: rename hpet module to "device" Paolo Bonzini
2025-05-30  7:11 ` [PULL 12/77] target/i386/emulate: more lflags cleanups Paolo Bonzini
2025-05-30  7:11 ` [PULL 13/77] rocker: do not pollute the namespace Paolo Bonzini
2025-06-10  7:53   ` Philippe Mathieu-Daudé
2025-06-10  7:54     ` Philippe Mathieu-Daudé
2025-05-30  7:11 ` [PULL 14/77] i386: Introduce tdx-guest object Paolo Bonzini
2025-05-30  7:11 ` [PULL 15/77] i386/tdx: Implement tdx_kvm_type() for TDX Paolo Bonzini
2025-05-30  7:11 ` [PULL 16/77] i386/tdx: Implement tdx_kvm_init() to initialize TDX VM context Paolo Bonzini
2025-05-30  7:11 ` [PULL 17/77] i386/tdx: Get tdx_capabilities via KVM_TDX_CAPABILITIES Paolo Bonzini
2025-05-30  7:11 ` [PULL 18/77] i386/tdx: Introduce is_tdx_vm() helper and cache tdx_guest object Paolo Bonzini
2025-05-30  7:11 ` [PULL 19/77] kvm: Introduce kvm_arch_pre_create_vcpu() Paolo Bonzini
2025-05-30  7:11 ` [PULL 20/77] i386/tdx: Initialize TDX before creating TD vcpus Paolo Bonzini
2025-07-17  9:40   ` Peter Maydell
2025-07-17 10:10     ` Xiaoyao Li
2025-05-30  7:11 ` [PULL 21/77] i386/tdx: Add property sept-ve-disable for tdx-guest object Paolo Bonzini
2025-05-30  7:11 ` [PULL 22/77] i386/tdx: Make sept_ve_disable set by default Paolo Bonzini
2025-05-30  7:11 ` [PULL 23/77] i386/tdx: Wire CPU features up with attributes of TD guest Paolo Bonzini
2025-05-30  7:11 ` [PULL 24/77] i386/tdx: Validate TD attributes Paolo Bonzini
2025-05-30  7:11 ` [PULL 25/77] i386/tdx: Support user configurable mrconfigid/mrowner/mrownerconfig Paolo Bonzini
2025-05-30  7:11 ` [PULL 26/77] i386/tdx: Set APIC bus rate to match with what TDX module enforces Paolo Bonzini
2025-05-30  7:11 ` [PULL 27/77] i386/tdx: Implement user specified tsc frequency Paolo Bonzini
2025-05-30  7:11 ` [PULL 28/77] i386/tdx: load TDVF for TD guest Paolo Bonzini
2025-05-30  7:11 ` [PULL 29/77] i386/tdvf: Introduce function to parse TDVF metadata Paolo Bonzini
2025-05-30  7:12 ` [PULL 30/77] i386/tdx: Parse TDVF metadata for TDX VM Paolo Bonzini
2025-05-30  7:12 ` [PULL 31/77] i386/tdx: Don't initialize pc.rom for TDX VMs Paolo Bonzini
2025-05-30  7:12 ` [PULL 32/77] i386/tdx: Track mem_ptr for each firmware entry of TDVF Paolo Bonzini
2025-05-30  7:12 ` [PULL 33/77] i386/tdx: Track RAM entries for TDX VM Paolo Bonzini
2025-05-30  7:12 ` [PULL 34/77] headers: Add definitions from UEFI spec for volumes, resources, etc Paolo Bonzini
2025-05-30  7:12 ` [PULL 35/77] i386/tdx: Setup the TD HOB list Paolo Bonzini
2025-05-30  7:12 ` [PULL 36/77] i386/tdx: Add TDVF memory via KVM_TDX_INIT_MEM_REGION Paolo Bonzini
2025-05-30  7:12 ` [PULL 37/77] i386/tdx: Call KVM_TDX_INIT_VCPU to initialize TDX vcpu Paolo Bonzini
2025-05-30  7:12 ` [PULL 38/77] i386/tdx: Finalize TDX VM Paolo Bonzini
2025-05-30  7:12 ` [PULL 39/77] i386/tdx: Enable user exit on KVM_HC_MAP_GPA_RANGE Paolo Bonzini
2025-05-30  7:12 ` [PULL 40/77] i386/tdx: Handle KVM_SYSTEM_EVENT_TDX_FATAL Paolo Bonzini
2025-05-30  7:12 ` [PULL 41/77] i386/tdx: Wire TDX_REPORT_FATAL_ERROR with GuestPanic facility Paolo Bonzini
2025-05-30  7:12 ` [PULL 42/77] kvm: Check KVM_CAP_MAX_VCPUS at vm level Paolo Bonzini
2025-05-30  7:12 ` [PULL 43/77] i386/cpu: introduce x86_confidential_guest_cpu_instance_init() Paolo Bonzini
2025-05-30  7:12 ` [PULL 44/77] i386/tdx: implement tdx_cpu_instance_init() Paolo Bonzini
2025-05-30  7:12 ` [PULL 45/77] i386/cpu: Introduce enable_cpuid_0x1f to force exposing CPUID 0x1f Paolo Bonzini
2025-05-30  7:12 ` [PULL 46/77] i386/tdx: Force " Paolo Bonzini
2025-05-30  7:12 ` [PULL 47/77] i386/tdx: Set kvm_readonly_mem_enabled to false for TDX VM Paolo Bonzini
2025-05-30  7:12 ` [PULL 48/77] i386/tdx: Disable SMM for TDX VMs Paolo Bonzini
2025-05-30  7:12 ` [PULL 49/77] i386/tdx: Disable PIC " Paolo Bonzini
2025-05-30  7:12 ` [PULL 50/77] i386/tdx: Set and check kernel_irqchip mode for TDX Paolo Bonzini
2025-05-30  7:12 ` [PULL 51/77] i386/tdx: Don't synchronize guest tsc for TDs Paolo Bonzini
2025-05-30  7:12 ` [PULL 52/77] i386/tdx: Only configure MSR_IA32_UCODE_REV in kvm_init_msrs() " Paolo Bonzini
2025-05-30  7:12 ` [PULL 53/77] i386/apic: Skip kvm_apic_put() for TDX Paolo Bonzini
2025-05-30  7:12 ` [PULL 54/77] cpu: Don't set vcpu_dirty when guest_state_protected Paolo Bonzini
2025-05-30  7:12 ` [PULL 55/77] i386/cgs: Rename *mask_cpuid_features() to *adjust_cpuid_features() Paolo Bonzini
2025-05-30  7:12 ` Paolo Bonzini [this message]
2025-05-30  7:12 ` [PULL 57/77] i386/tdx: Add TDX fixed1 bits to supported CPUIDs Paolo Bonzini
2025-05-30  7:12 ` [PULL 58/77] i386/tdx: Add supported CPUID bits related to TD Attributes Paolo Bonzini
2025-05-30  7:12 ` [PULL 59/77] i386/tdx: Add supported CPUID bits relates to XFAM Paolo Bonzini
2025-07-10 12:27   ` Peter Maydell
2025-07-10 12:42     ` Xiaoyao Li
2025-07-10 12:57       ` Peter Maydell
2025-05-30  7:12 ` [PULL 60/77] i386/tdx: Add XFD to supported bit of TDX Paolo Bonzini
2025-05-30  7:12 ` [PULL 61/77] i386/tdx: Define supported KVM features for TDX Paolo Bonzini
2025-05-30  7:12 ` [PULL 62/77] i386/cgs: Introduce x86_confidential_guest_check_features() Paolo Bonzini
2025-05-30  7:12 ` [PULL 63/77] i386: Remove unused parameter "uint32_t bit" in feature_word_description() Paolo Bonzini
2025-05-30  7:12 ` [PULL 64/77] target/i386: Print CPUID subleaf info for unsupported feature Paolo Bonzini
2025-05-30  7:12 ` [PULL 65/77] i386/tdx: Fetch and validate CPUID of TD guest Paolo Bonzini
2025-05-30  7:12 ` [PULL 66/77] i386/tdx: Don't treat SYSCALL as unavailable Paolo Bonzini
2025-05-30  7:12 ` [PULL 67/77] i386/tdx: Make invtsc default on Paolo Bonzini
2025-05-30  7:12 ` [PULL 68/77] i386/tdx: Validate phys_bits against host value Paolo Bonzini
2025-05-30  7:12 ` [PULL 69/77] docs: Add TDX documentation Paolo Bonzini
2025-05-30  7:12 ` [PULL 70/77] rust: make declaration of dependent crates more consistent Paolo Bonzini
2025-05-30  7:12 ` [PULL 71/77] target/i386: Update EPYC CPU model for Cache property, RAS, SVM feature bits Paolo Bonzini
2025-05-30  7:12 ` [PULL 72/77] target/i386: Update EPYC-Rome " Paolo Bonzini
2025-05-30  7:12 ` [PULL 73/77] target/i386: Update EPYC-Milan " Paolo Bonzini
2025-05-30  7:12 ` [PULL 74/77] target/i386: Add couple of feature bits in CPUID_Fn80000021_EAX Paolo Bonzini
2025-05-30  7:12 ` [PULL 75/77] target/i386: Update EPYC-Genoa for Cache property, perfmon-v2, RAS and SVM feature bits Paolo Bonzini
2025-05-30  7:12 ` [PULL 76/77] target/i386: Add support for EPYC-Turin model Paolo Bonzini
2025-05-30  7:12 ` [PULL 77/77] target/i386/tcg/helper-tcg: fix file references in comments Paolo Bonzini
2025-05-31 23:05 ` [PULL 00/77] i386, build system changes for 2025-05-30 Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250530071250.2050910-57-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=xiaoyao.li@intel.com \
    --cc=zhao1.liu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).