[PATCH v6 47/60] i386/tdx: Implement adjust_cpuid_features() for TDX

Xiaoyao Li posted 60 patches 2 weeks, 4 days ago
[PATCH v6 47/60] i386/tdx: Implement adjust_cpuid_features() for TDX
Posted by Xiaoyao Li 2 weeks, 4 days ago
1. QEMU's support for Intel PT is borken in general, thus doesn't
   support for TDX.

2. Only limited KVM PV features are supported for TD guest.

3. Drop the AMD specific bits that are reserved on Intel platform.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 target/i386/kvm/tdx.c | 44 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
index 9dcb77e011bd..ba723db92bfe 100644
--- a/target/i386/kvm/tdx.c
+++ b/target/i386/kvm/tdx.c
@@ -33,6 +33,8 @@
 #include "kvm_i386.h"
 #include "tdx.h"
 
+#include "standard-headers/asm-x86/kvm_para.h"
+
 #define TDX_MIN_TSC_FREQUENCY_KHZ   (100 * 1000)
 #define TDX_MAX_TSC_FREQUENCY_KHZ   (10 * 1000 * 1000)
 
@@ -41,6 +43,14 @@
 #define TDX_TD_ATTRIBUTES_PKS               BIT_ULL(30)
 #define TDX_TD_ATTRIBUTES_PERFMON           BIT_ULL(63)
 
+#define TDX_SUPPORTED_KVM_FEATURES  ((1U << KVM_FEATURE_NOP_IO_DELAY) | \
+                                     (1U << KVM_FEATURE_PV_UNHALT) | \
+                                     (1U << KVM_FEATURE_PV_TLB_FLUSH) | \
+                                     (1U << KVM_FEATURE_PV_SEND_IPI) | \
+                                     (1U << KVM_FEATURE_POLL_CONTROL) | \
+                                     (1U << KVM_FEATURE_PV_SCHED_YIELD) | \
+                                     (1U << KVM_FEATURE_MSI_EXT_DEST_ID))
+
 static TdxGuest *tdx_guest;
 
 static struct kvm_tdx_capabilities *tdx_caps;
@@ -436,6 +446,39 @@ static void tdx_cpu_realizefn(X86ConfidentialGuest *cg, CPUState *cs,
     }
 }
 
+static uint32_t tdx_adjust_cpuid_features(X86ConfidentialGuest *cg,
+                                          uint32_t feature, uint32_t index,
+                                          int reg, uint32_t value)
+{
+    switch (feature) {
+    case 0x7:
+        if (index == 0 && reg == R_EBX) {
+            /* QEMU Intel PT support is broken */
+            value &= ~CPUID_7_0_EBX_INTEL_PT;
+        }
+        break;
+    case 0x40000001:
+        if (reg == R_EAX) {
+            value &= TDX_SUPPORTED_KVM_FEATURES;
+        }
+        break;
+    case 0x80000001:
+        if (reg == R_EDX) {
+            value &= ~CPUID_EXT2_AMD_ALIASES;
+        }
+        break;
+    case 0x80000008:
+        if (reg == R_EBX) {
+            value &= CPUID_8000_0008_EBX_WBNOINVD;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return value;
+}
+
 static int tdx_validate_attributes(TdxGuest *tdx, Error **errp)
 {
     if ((tdx->attributes & ~tdx_caps->supported_attrs)) {
@@ -781,4 +824,5 @@ static void tdx_guest_class_init(ObjectClass *oc, void *data)
     x86_klass->kvm_type = tdx_kvm_type;
     x86_klass->cpu_instance_init = tdx_cpu_instance_init;
     x86_klass->cpu_realizefn = tdx_cpu_realizefn;
+    x86_klass->adjust_cpuid_features = tdx_adjust_cpuid_features;
 }
-- 
2.34.1