Re: [PATCH v2 3/3] KVM: TDX: Enable Bus Lock VM exit
From: Xiaoyao Li
Date: Mon Aug 10 2026 - 21:44:59 EST
On 8/11/2026 9:18 AM, Edgecombe, Rick P wrote:
On Mon, 2026-08-10 at 19:22 +0800, Xiaoyao Li wrote:
Enable Bus Lock VM exit functionality for TDX guests.
Userspace can enable KVM_BUS_LOCK_DETECTION_EXIT for TDX guests without
getting an error, but the feature is not actually enabled because KVM
does not yet program the TDX execution control or handle the resulting
exit.
A bit run-on to me. Why not break it up like it's explained in patch 1.
Will update it to way how patch 1 describes.
Enable Bus Lock VM exit for TDX guests by programming the
BUS_LOCK_DETECTION control in the TD VMCS and by adding the exit handler.
Clear the bus_lock_detected bit to avoid being counted multiple times if
it needs to return early for wait_for_sept_zap case in tdx_vcpu_run().
Since the wait_for_sept_zap case is expected to be rare, just do the
clearing of bus_lock_detected unconditionally.
Note, there is no enumeration bit for this feature by TDX module because
all TDX modules support it, and allow to set the TD VMCS as long as the
hardware supports the feature.
Fixes: 161d34609f9b ("KVM: TDX: Make TDX VM type supported")
Cc: stable@xxxxxxxxxxxxxxx
Originally-by: Chenyi Qiang <chenyi.qiang@xxxxxxxxx>
Signed-off-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx>
---
Changes in v2:
- Don't overwrite the negative return value to 0. (Sashiko)
- Clear the bus_lock_detected bit when it returns early for
wait_for_sept_zap case.
- Add a note to clarify the feature is always supported by the TDX
module, to make Sashiko happy.
Ha! This is probably just being a bit funny. But let's treat AI review as
suggestions only. If it is a good feedback, it can stand on it's own.
yeah. Mostly for funny. I think the clarification itself makes sense.
---
arch/x86/kvm/vmx/tdx.c | 28 ++++++++++++++++++++++++++--
arch/x86/kvm/vmx/vmx.c | 2 +-
arch/x86/kvm/vmx/vmx.h | 1 +
3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index a89885d550c9..ac3f71643cd5 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1080,8 +1080,10 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
* allowing vCPU entry to avoid contention with tdh_vp_enter() and
* TDCALLs.
*/
- if (unlikely(READ_ONCE(to_kvm_tdx(vcpu->kvm)->wait_for_sept_zap)))
+ if (unlikely(READ_ONCE(to_kvm_tdx(vcpu->kvm)->wait_for_sept_zap))) {
+ vt->exit_reason.bus_lock_detected = 0;
return EXIT_FASTPATH_EXIT_HANDLED;
+ }
Hmm. Why is this the only part of exit_reason that we care about in this
scenario?
Because it's the only path on TDX that it returns without updating the vt->exit_reason. All the other cases go to tdx_vcpu_enter_exit() and tdx_vcpu_enter_exit() updates the vt->exit_reason.
I went and looked for similar scenarios on the VMX side to see what it did, and
didn't find any. Same for you?
VMX can return early without reaching vmx_vcpu_enter_exit() as well. But VMX ensures vt->exit_reason is updated when it returns early.
trace_kvm_entry(vcpu, run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT);
@@ -2037,7 +2039,7 @@ int tdx_complete_emulated_msr(struct kvm_vcpu *vcpu, int err)
}
-int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
+static int __tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
{
struct vcpu_tdx *tdx = to_tdx(vcpu);
u64 vp_enter_ret = tdx->vp_enter_ret;
@@ -2138,6 +2140,8 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
case EXIT_REASON_NOTIFY:
/* NMI blocking state is handled by TDX module */
return __vmx_handle_notify(vcpu, vmx_get_exit_qual(vcpu));
+ case EXIT_REASON_BUS_LOCK:
+ return handle_bus_lock_vmexit(vcpu);
default:
break;
}
@@ -2147,6 +2151,22 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
return 0;
}
+int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
+{
+ int ret = __tdx_handle_exit(vcpu, fastpath);
+
+ /* Exit to user space when bus lock was detected */
+ if (vmx_get_exit_reason(vcpu).bus_lock_detected) {
+ if (ret > 0) {
+ vcpu->run->exit_reason = KVM_EXIT_X86_BUS_LOCK;
+ ret = 0;
+ }
+
+ vcpu->run->flags |= KVM_RUN_X86_BUS_LOCK;
+ }
+ return ret;
+}
Ok, so the plan is to consolidate this duplication on top of the backportable
fix.
yes. The consolidation also requires to first fix the VMX part[1]. So this series only contains the necessary things that need to be backported to stable kernels.
[1] https://lore.kernel.org/all/20260806111923.1990562-2-xiaoyao.li@xxxxxxxxx/