aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2024-07-03 11:12:06 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2024-07-04 07:47:11 +0200
commitc28d8b097f6da0389d0e915e26ab210aaac38ba0 (patch)
treeb90211059842e5bab07d98c41f33d1a4fdf7d30a /target
parenta0124e333e2176640f233e5ea57a2f413985d9b5 (diff)
downloadqemu-c28d8b097f6da0389d0e915e26ab210aaac38ba0.zip
qemu-c28d8b097f6da0389d0e915e26ab210aaac38ba0.tar.gz
qemu-c28d8b097f6da0389d0e915e26ab210aaac38ba0.tar.bz2
target/i386: add support for masking CPUID features in confidential guests
Some CPUID features may be provided by KVM for some guests, independent of processor support, for example TSC deadline or TSC adjust. If these are not supported by the confidential computing firmware, however, the guest will fail to start. Add support for removing unsupported features from "-cpu host". Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target')
-rw-r--r--target/i386/confidential-guest.h24
-rw-r--r--target/i386/kvm/kvm.c5
2 files changed, 29 insertions, 0 deletions
diff --git a/target/i386/confidential-guest.h b/target/i386/confidential-guest.h
index 532e172..7342d28 100644
--- a/target/i386/confidential-guest.h
+++ b/target/i386/confidential-guest.h
@@ -39,6 +39,8 @@ struct X86ConfidentialGuestClass {
/* <public> */
int (*kvm_type)(X86ConfidentialGuest *cg);
+ uint32_t (*mask_cpuid_features)(X86ConfidentialGuest *cg, uint32_t feature, uint32_t index,
+ int reg, uint32_t value);
};
/**
@@ -56,4 +58,26 @@ static inline int x86_confidential_guest_kvm_type(X86ConfidentialGuest *cg)
return 0;
}
}
+
+/**
+ * x86_confidential_guest_mask_cpuid_features:
+ *
+ * Removes unsupported features from a confidential guest's CPUID values, returns
+ * the value with the bits removed. The bits removed should be those that KVM
+ * provides independent of host-supported CPUID features, but are not supported by
+ * the confidential computing firmware.
+ */
+static inline int x86_confidential_guest_mask_cpuid_features(X86ConfidentialGuest *cg,
+ uint32_t feature, uint32_t index,
+ int reg, uint32_t value)
+{
+ X86ConfidentialGuestClass *klass = X86_CONFIDENTIAL_GUEST_GET_CLASS(cg);
+
+ if (klass->mask_cpuid_features) {
+ return klass->mask_cpuid_features(cg, feature, index, reg, value);
+ } else {
+ return value;
+ }
+}
+
#endif
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index dd8b0f3..056d117 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -548,6 +548,11 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
ret |= 1U << KVM_HINTS_REALTIME;
}
+ if (current_machine->cgs) {
+ ret = x86_confidential_guest_mask_cpuid_features(
+ X86_CONFIDENTIAL_GUEST(current_machine->cgs),
+ function, index, reg, ret);
+ }
return ret;
}