[PATCH v4 3/9] KVM: TDX: Set bits 31:16 to 0 for the synthesized Exit Reason
From: Xiaoyao Li
Date: Wed Aug 19 2026 - 05:56:37 EST
Set bits 31:16 to 0 instead of all-1s for KVM's synthesized Exit Reason.
KVM is going to support Bus Lock VM exit for TDX, after which bit 26 of
the Exit Reason becomes meaningful and indicates that a bus lock happened.
The existing synthesized Exit Reason, -1u, will cause a false positive in
that case. Change the synthesized Exit Reason from -1u to U16_MAX, so that
bits 31:16 are set to 0. This also avoids the potential issues when other
bits in 31:16 become valid in the future.
As a bonus, the check for synthesized Exit Reason in tdx_failed_vmentry()
becomes unnecessary. Just drop it.
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx>
---
Note, the checking of tdx_failed_vmentry() looks to miss the case where
a real EPT_MISCONFIG happens with failed_vmentry being set. First, in
practice, EPT_MISCONFIG cannot happen with failed_vmentry being set.
Second, even if it can, this is a pre-existing issue and the next
patch can address it.
Changes in v4:
- Collect R-b from Rick.
Changes in v3:
- split from the patch 2 in v2.
- define a MARCO for the synthesized invalid Exit Reason.
---
arch/x86/kvm/vmx/tdx.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 1dead84e6077..4e275cb6927a 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -935,13 +935,21 @@ static __always_inline bool tdx_is_exit_reason_valid(u64 vp_enter_ret)
}
}
+/* Synthesized invalid Exit Reason */
+#define TDX_INVALID_EXIT_REASON U16_MAX
+
static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
{
struct vcpu_tdx *tdx = to_tdx(vcpu);
u32 exit_reason;
+ /*
+ * Return the synthesized invalid Exit Reason, as the TDX module
+ * never attempted to run the vCPU, i.e. the Exit Reason is undefined,
+ * but this is NOT a failed VM-Enter.
+ */
if (!tdx_is_exit_reason_valid(tdx->vp_enter_ret))
- return -1u;
+ return TDX_INVALID_EXIT_REASON;
exit_reason = tdx->vp_enter_ret;
@@ -956,7 +964,7 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
* Defer KVM_BUG_ON() until tdx_handle_exit() because this is in
* non-instrumentable code with interrupts disabled.
*/
- return -1u;
+ return TDX_INVALID_EXIT_REASON;
default:
break;
}
@@ -987,8 +995,7 @@ static noinstr void tdx_vcpu_enter_exit(struct kvm_vcpu *vcpu)
static bool tdx_failed_vmentry(struct kvm_vcpu *vcpu)
{
- return vmx_get_exit_reason(vcpu).failed_vmentry &&
- vmx_get_exit_reason(vcpu).full != -1u;
+ return vmx_get_exit_reason(vcpu).failed_vmentry;
}
static fastpath_t tdx_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
--
2.43.0