[PATCH v2 17/17] KVM: TDX: Support event-notify interrupts only with userspace Quoting
From: Xu Yilun
Date: Thu Jun 18 2026 - 04:49:29 EST
From: Peter Fang <peter.fang@xxxxxxxxx>
Tie userspace SetupEventNotifyInterrupt support to userspace Quote
generation. Delivering event-notify interrupts via userspace breaks if
KVM never exits to userspace in the first place.
This is an optional capability to notify the guest when Quoting has
completed. No known guest currently uses it, so defer adding in-kernel
support for now. The Linux TDX guest relies on polling only.
Signed-off-by: Peter Fang <peter.fang@xxxxxxxxx>
Signed-off-by: Xu Yilun <yilun.xu@xxxxxxxxxxxxxxx>
---
arch/x86/kvm/vmx/tdx.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 20558b0185b6..25146da3933f 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -185,7 +185,7 @@ static void td_init_cpuid_entry2(struct kvm_cpuid_entry2 *entry, unsigned char i
tdx_clear_unsupported_cpuid(entry);
}
-#define TDVMCALLINFO_SETUP_EVENT_NOTIFY_INTERRUPT BIT(1)
+#define TDVMCALLINFO_SETUP_EVENT_NOTIFY_INTERRUPT BIT_ULL(1)
static int init_kvm_tdx_caps(const struct tdx_sys_info_td_conf *td_conf,
struct kvm_tdx_capabilities *caps)
@@ -202,8 +202,15 @@ static int init_kvm_tdx_caps(const struct tdx_sys_info_td_conf *td_conf,
caps->cpuid.nent = td_conf->num_cpuid_config;
- caps->user_tdvmcallinfo_1_r11 =
- TDVMCALLINFO_SETUP_EVENT_NOTIFY_INTERRUPT;
+ /*
+ * Don't advertise userspace event-notify interrupt support if TDX
+ * quoting service is enabled, as quote generation will be handled
+ * entirely in the kernel. Support in the kernel can be added later.
+ */
+ if (!tdx_quote_enabled()) {
+ caps->user_tdvmcallinfo_1_r11 |=
+ TDVMCALLINFO_SETUP_EVENT_NOTIFY_INTERRUPT;
+ }
for (i = 0; i < td_conf->num_cpuid_config; i++)
td_init_cpuid_entry2(&caps->cpuid.entries[i], i);
@@ -1684,9 +1691,16 @@ static int tdx_get_quote(struct kvm_vcpu *vcpu)
static int tdx_setup_event_notify_interrupt(struct kvm_vcpu *vcpu)
{
+ struct kvm_tdx *kvm_tdx = to_kvm_tdx(vcpu->kvm);
struct vcpu_tdx *tdx = to_tdx(vcpu);
u64 vector = tdx->vp_enter_args.r12;
+ /* See comment in init_kvm_tdx_caps() */
+ if (kvm_tdx->get_quote_in_kernel) {
+ tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED);
+ return 1;
+ }
+
if (vector < 32 || vector > 255) {
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
return 1;
--
2.25.1