[PATCH v2 2/3] KVM: TDX: Synthesize SHUTDOWN instead of returning -EIO on unhandled EPT violation

From: Sean Christopherson

Date: Tue Sep 29 2026 - 20:14:25 EST


Exit to userspace with KVM_EXIT_SHUTDOWN instead of returning -EIO from
KVM_RUN if KVM encounters an EPT Violation due to a guest access to a
pending page. Returning -EIO implies KVM is buggy, and most VMMs will
respond by completely terminating the VM, versus rebooting the VM in
response to KVM_EXIT_SHUTDOWN. I.e. give the VMM the option of trying to
keep the VM (from the end user's perspective) alive.

Ideally, KVM would probably exit with KVM_EXIT_MEMORY_FAULT, but KVM would
need to extend run->memory_fault so that userspace knows the fault can't be
handled. This scenario specifically occurs when the guest has deliberately
disabled #VEs on unaccepted memory for security purposes, i.e. the guest
literally disabled the mechanism that tells it it screwed up. But, because
this is fatal, and the whole point is to NOT try to fixup the fault,
jumping through hoops to return MEMORY_FAULT instead of SHUTDOWN doesn't
make a whole lot of sense.

Don't bother bouncing through KVM_REQ_TRIPLE_FAULT as
tdx_handle_ept_violation() is a top-level exit handler, i.e. there is no
need to worry about failing to actually exit to userspace.

Fixes: e6a85781f783 ("KVM: TDX: Detect unexpected SEPT violations due to pending SPTEs")
Cc: stable@xxxxxxxxxxxxxxx
Cc: James Houghton <jthoughton@xxxxxxxxxx>
Cc: Xiaoyao Li <xiaoyao.li@xxxxxxxxx>
Cc: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx>
Cc: Yan Zhao <yan.y.zhao@xxxxxxxxx>
Cc: Binbin Wu <binbin.wu@xxxxxxxxxxxxxxx>
Cc: Ackerley Tng <ackerleytng@xxxxxxxxxx>
Cc: Vishal Annapurve <vannapurve@xxxxxxxxxx>
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/kvm/vmx/tdx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 29d4751f37fb..e3723f1222fc 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1939,8 +1939,8 @@ static int tdx_handle_ept_violation(struct kvm_vcpu *vcpu)
if (tdx_is_sept_violation_unexpected_pending(vcpu)) {
pr_warn("Guest access before accepting 0x%llx on vCPU %d\n",
gpa, vcpu->vcpu_id);
- kvm_vm_dead(vcpu->kvm);
- return -EIO;
+ kvm_prepare_shutdown_exit(vcpu);
+ return 0;
}
/*
* Always treat SEPT violations as write faults. Ignore the
--
2.56.0.rc1.315.gc6ed9934b7-goog