* [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX
@ 2026-08-19 9:48 Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 1/9] KVM: TDX: Enable Notify VM exit Xiaoyao Li
` (8 more replies)
0 siblings, 9 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:48 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
Hi all,
This is v4 of the series to enable the Notify VM Exit and Bus Lock VM
exit for TDX, which fixes the KVM CAP issue related with them and allow
userspace to actually enable the features.
Compared to v3, this v4 adds 5 more patches. The first 8 patches target
for stable kernels while only the patch 9 doesn't have to. Patch 1 is a
single patch to enable Notify VM exit for TDX. Except patch 6, patch
2-7 are mandatory for enabling Bus Lock VM exit for TDX in patch 8.
Patch 6 itself is a fix for VMX and is OK for cc stable though maybe not
necessary. Patch 6 is added to this series since it can help stop Sashiko
repeating its finding of VMX's pre-existing issue, and it's also necessary
for patch 9 to consilidate the exit handler for VMX and TDX.
There are other issues of existing code found during previous review, like
the EPT MISCONFIG handling. Given they are not mandatory for enabling the
Notify VM exit and Bus Lock VM exit for TDX, the plan is to address them in
a follow-up series separately.
Please refer to v1 for a full background.
v3: https://lore.kernel.org/all/20260812080229.2481439-1-xiaoyao.li@intel.com/
v2: https://lore.kernel.org/all/20260810112200.2326727-1-xiaoyao.li@intel.com/
v1: https://lore.kernel.org/all/20260805031257.1844914-1-xiaoyao.li@intel.com/
Xiaoyao Li (9):
KVM: TDX: Enable Notify VM exit
KVM: TDX: Check if there is valid exit infos based on vp_enter_ret
KVM: TDX: Set bits 31:16 to 0 for the synthesized Exit Reason
KVM: TDX: Don't assume exit_reason[31:16] is all-0 in
tdx_to_vmx_exit_reason()
KVM: TDX: Update exit_reason on wait_for_sept_zap return
KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus
lock detected
KVM: VMX: Make handle_bus_lock_vmexit() a shared helper
KVM: TDX: Enable Bus Lock VM exit
KVM: VMX: Consolidate the exit handler for VMX and TDX
arch/x86/kvm/vmx/common.h | 20 ++++++++++
arch/x86/kvm/vmx/main.c | 49 ++++++++++++++++++-----
arch/x86/kvm/vmx/tdx.c | 82 ++++++++++++++++++++++++++++++---------
arch/x86/kvm/vmx/vmx.c | 46 ++--------------------
4 files changed, 126 insertions(+), 71 deletions(-)
base-commit: 1b731e5ded480bd1e5546aed35584238661ce72e
--
2.43.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 1/9] KVM: TDX: Enable Notify VM exit
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
@ 2026-08-19 9:48 ` Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 2/9] KVM: TDX: Check if there is valid exit infos based on vp_enter_ret Xiaoyao Li
` (7 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:48 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
Enable Notify VM exit functionality for TDX guests.
Notify VM exit is an existing feature supported by KVM. Userspace can
enable Notify VM exit through KVM_CAP_X86_NOTIFY_VMEXIT when it's
reported as supported. However, KVM reports the support of this CAP just
based on the hardware capability but doesn't differentiate between VMX
and TDX. This leads to the issue that userspace can enable this cap for
TDX guests without getting an error, but the feature is not actually
enabled because KVM doesn't call the TDX module API to program the
relevant TD VMCS fields.
Enable Notify VM exit for TDX guests by:
- Invoking TDX module API calls to set NOTIFY_VM_EXITING and Notify
Window in TD VMCS. It's done in tdx_vcpu_init() where other TD VMCS
bits are set. Since TDX vCPU cannot be reset, it only needs to be
configured once when initializing the TDX vCPU.
- Adding corresponding exit handler for TDX Notify VM Exit.
Notify VM exit can happen when executing the IRET instruction. If the
IRET unblocks the NMI blocking state, bit 12 of the exit qualification
is set. In this case, the VMM needs to restore the "blocked by NMI" state
when it decides to re-enter the guest. For TDX, KVM cannot manage the
GUEST_INTERRUPTIBILITY_INFO and it's TDX module's responsibility to
handle it. Extract the common part without NMI blocking handling into a
helper in common.h so that it can be shared between VMX and TDX.
Note, KVM uses "pre-production" terminology for the feature formally called
Notify VM-Exit. All public versions of the SDM refer to the feature as
Instruction Timeout. This will be remedied in the near future, for now,
use KVM's terminology for consistency.
Note, #2, there is no enumeration bit for Notify VM exit by TDX module
because all TDX modules support it, and allow to set the corresponding
TD VMCS fields as long as the hardware supports the feature.
Fixes: 161d34609f9b ("KVM: TDX: Make TDX VM type supported")
Cc: stable@vger.kernel.org
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
Changes in v4:
- rename __vmx_handle_notify() to __vt_handle_notify(), to better
reflect it is a shared helper for both VMX and TDX.
Changes in v3:
- Collect R-b tag from Rick.
Changes in v2:
- Mention the feature name mismatch between KVM and SDM in changelog and
leave the renaming to future, since this patch is targeted for stable
- Extract the common handling into a helper, and put the helper in
common.h instead of refactorin the existing handle_notify() in vmx.h
- Add a note to clarify the feature is always supported by TDX module,
to make Sashiko happy.
---
arch/x86/kvm/vmx/common.h | 19 +++++++++++++++++++
arch/x86/kvm/vmx/tdx.c | 10 ++++++++++
arch/x86/kvm/vmx/vmx.c | 13 +------------
3 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h
index 08005676702c..7fce1bbabc78 100644
--- a/arch/x86/kvm/vmx/common.h
+++ b/arch/x86/kvm/vmx/common.h
@@ -4,6 +4,7 @@
#include <linux/kvm_host.h>
#include <asm/posted_intr.h>
+#include <asm/vmx.h>
#include "mmu.h"
@@ -183,6 +184,24 @@ static inline void __vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu,
kvm_vcpu_trigger_posted_interrupt(vcpu, POSTED_INTR_VECTOR);
}
+static inline int __vt_handle_notify(struct kvm_vcpu *vcpu,
+ unsigned long exit_qual)
+{
+ bool context_invalid = exit_qual & NOTIFY_VM_CONTEXT_INVALID;
+
+ ++vcpu->stat.notify_window_exits;
+
+ if (vcpu->kvm->arch.notify_vmexit_flags & KVM_X86_NOTIFY_VMEXIT_USER ||
+ context_invalid) {
+ vcpu->run->exit_reason = KVM_EXIT_NOTIFY;
+ vcpu->run->notify.flags = context_invalid ?
+ KVM_NOTIFY_CONTEXT_INVALID : 0;
+ return 0;
+ }
+
+ return 1;
+}
+
noinstr void vmx_handle_nmi(struct kvm_vcpu *vcpu);
#endif /* __KVM_X86_VMX_COMMON_H */
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index b272c20586a7..d557840687d2 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -2126,6 +2126,9 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
* - If it's not an MSMI, no need to do anything here.
*/
return 1;
+ case EXIT_REASON_NOTIFY:
+ /* NMI blocking state is handled by TDX module */
+ return __vt_handle_notify(vcpu, vmx_get_exit_qual(vcpu));
default:
break;
}
@@ -3154,6 +3157,13 @@ static int tdx_vcpu_init(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *cmd)
td_vmcs_write64(tdx, POSTED_INTR_DESC_ADDR, __pa(&tdx->vt.pi_desc));
td_vmcs_setbit32(tdx, PIN_BASED_VM_EXEC_CONTROL, PIN_BASED_POSTED_INTR);
+ if (kvm_notify_vmexit_enabled(vcpu->kvm)) {
+ td_vmcs_setbit32(tdx, SECONDARY_VM_EXEC_CONTROL,
+ SECONDARY_EXEC_NOTIFY_VM_EXITING);
+ td_vmcs_write32(tdx, NOTIFY_WINDOW,
+ vcpu->kvm->arch.notify_window);
+ }
+
tdx->state = VCPU_TD_STATE_INITIALIZED;
return 0;
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index e3bfe6aca1a0..35ac9ddffaf4 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6279,9 +6279,6 @@ static int handle_bus_lock_vmexit(struct kvm_vcpu *vcpu)
static int handle_notify(struct kvm_vcpu *vcpu)
{
unsigned long exit_qual = vmx_get_exit_qual(vcpu);
- bool context_invalid = exit_qual & NOTIFY_VM_CONTEXT_INVALID;
-
- ++vcpu->stat.notify_window_exits;
/*
* Notify VM exit happened while executing iret from NMI,
@@ -6291,15 +6288,7 @@ static int handle_notify(struct kvm_vcpu *vcpu)
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
GUEST_INTR_STATE_NMI);
- if (vcpu->kvm->arch.notify_vmexit_flags & KVM_X86_NOTIFY_VMEXIT_USER ||
- context_invalid) {
- vcpu->run->exit_reason = KVM_EXIT_NOTIFY;
- vcpu->run->notify.flags = context_invalid ?
- KVM_NOTIFY_CONTEXT_INVALID : 0;
- return 0;
- }
-
- return 1;
+ return __vt_handle_notify(vcpu, exit_qual);
}
static int vmx_get_msr_imm_reg(struct kvm_vcpu *vcpu)
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 2/9] KVM: TDX: Check if there is valid exit infos based on vp_enter_ret
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 1/9] KVM: TDX: Enable Notify VM exit Xiaoyao Li
@ 2026-08-19 9:48 ` Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 3/9] KVM: TDX: Set bits 31:16 to 0 for the synthesized Exit Reason Xiaoyao Li
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:48 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
Check if there is valid exit info based on vp_enter_ret instead of relying
on the clobbered Exit Reason, in tdx_get_exit_info().
Current KVM uses "Exit Reason is not equal to the synthesized invalid
Exit Reason, -1u," as the condition to identify there is a real TD Exit
and valid exit infos. However, there is one issue with this approach:
KVM updates the Exit Reason to the synthesized invalid Exit Reason for
real EPT MISCONFIG as well. This is a false positive for real EPT
MISCONFIG, which has valid exit infos.
Though the issue can be addressed by changing the handling for real EPT
MISCONFIG to not update the Exit Reason to the synthesized one, relying
on the clobbered Exit Reason itself is brittle. Instead, check
vp_enter_ret directly to identify if it is a valid Exit Reason.
Fixes: da407fe45908 ("KVM: TDX: Handle EPT violation/misconfig exit")
Cc: stable@vger.kernel.org
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
Changes in v4:
- new patch.
---
arch/x86/kvm/vmx/tdx.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index d557840687d2..1dead84e6077 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -921,21 +921,27 @@ static __always_inline u32 tdcall_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
return EXIT_REASON_TDCALL;
}
-static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
+static __always_inline bool tdx_is_exit_reason_valid(u64 vp_enter_ret)
{
- struct vcpu_tdx *tdx = to_tdx(vcpu);
- u32 exit_reason;
-
- switch (tdx->vp_enter_ret & TDX_SEAMCALL_STATUS_MASK) {
+ switch (vp_enter_ret & TDX_SEAMCALL_STATUS_MASK) {
case TDX_SUCCESS:
case TDX_NON_RECOVERABLE_VCPU:
case TDX_NON_RECOVERABLE_TD:
case TDX_NON_RECOVERABLE_TD_NON_ACCESSIBLE:
case TDX_NON_RECOVERABLE_TD_WRONG_APIC_MODE:
- break;
+ return true;
default:
- return -1u;
+ return false;
}
+}
+
+static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_tdx *tdx = to_tdx(vcpu);
+ u32 exit_reason;
+
+ if (!tdx_is_exit_reason_valid(tdx->vp_enter_ret))
+ return -1u;
exit_reason = tdx->vp_enter_ret;
@@ -2144,7 +2150,7 @@ void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
struct vcpu_tdx *tdx = to_tdx(vcpu);
*reason = tdx->vt.exit_reason.full;
- if (*reason != -1u) {
+ if (tdx_is_exit_reason_valid(tdx->vp_enter_ret)) {
*info1 = vmx_get_exit_qual(vcpu);
*info2 = tdx->ext_exit_qualification;
*intr_info = vmx_get_intr_info(vcpu);
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 3/9] KVM: TDX: Set bits 31:16 to 0 for the synthesized Exit Reason
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 1/9] KVM: TDX: Enable Notify VM exit Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 2/9] KVM: TDX: Check if there is valid exit infos based on vp_enter_ret Xiaoyao Li
@ 2026-08-19 9:48 ` Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 4/9] KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason() Xiaoyao Li
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:48 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
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@vger.kernel.org
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
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
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 4/9] KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason()
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
` (2 preceding siblings ...)
2026-08-19 9:48 ` [PATCH v4 3/9] KVM: TDX: Set bits 31:16 to 0 for the synthesized Exit Reason Xiaoyao Li
@ 2026-08-19 9:48 ` Xiaoyao Li
2026-08-19 10:16 ` sashiko-bot
2026-08-19 9:48 ` [PATCH v4 5/9] KVM: TDX: Update exit_reason on wait_for_sept_zap return Xiaoyao Li
` (4 subsequent siblings)
8 siblings, 1 reply; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:48 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
When handling the real Exit Reason, don't assume the upper 16 bits as
all-0 in tdx_to_vmx_exit_reason(), in preparation for enabling Bus Lock
VM exit.
When Bus Lock VM exit is enabled, the bit 26 of Exit Reason becomes
valid and it can be 1 with various exit reasons. Change the logic in
tdx_to_vmx_exit_reason() to check the 'basic' Exit Reason for correctness.
Also preserve bit[31:16] when changing the (basic) Exit Reason, to not
lose the information in bit[31:16].
Change the return type of tdx_to_vmx_exit_reason() to
"union vmx_exit_reason" for the convenience of manipulating the basic
field.
Fixes: c42856af8f70 ("KVM: TDX: Add a place holder for handler of TDX hypercalls (TDG.VP.VMCALL)")
Cc: stable@vger.kernel.org
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
Changes in v3:
- new patch split from patch 2 of v2.
---
arch/x86/kvm/vmx/tdx.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 4e275cb6927a..987092283955 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -938,10 +938,10 @@ 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)
+static __always_inline union vmx_exit_reason tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
{
struct vcpu_tdx *tdx = to_tdx(vcpu);
- u32 exit_reason;
+ union vmx_exit_reason exit_reason;
/*
* Return the synthesized invalid Exit Reason, as the TDX module
@@ -949,22 +949,26 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
* but this is NOT a failed VM-Enter.
*/
if (!tdx_is_exit_reason_valid(tdx->vp_enter_ret))
- return TDX_INVALID_EXIT_REASON;
+ return (union vmx_exit_reason) {
+ .basic = TDX_INVALID_EXIT_REASON,
+ };
- exit_reason = tdx->vp_enter_ret;
+ exit_reason.full = (u32)tdx->vp_enter_ret;
- switch (exit_reason) {
+ switch (exit_reason.basic) {
case EXIT_REASON_TDCALL:
if (tdvmcall_exit_type(vcpu))
- return EXIT_REASON_VMCALL;
-
- return tdcall_to_vmx_exit_reason(vcpu);
+ exit_reason.basic = EXIT_REASON_VMCALL;
+ else
+ exit_reason.basic = tdcall_to_vmx_exit_reason(vcpu);
+ break;
case EXIT_REASON_EPT_MISCONFIG:
/*
* Defer KVM_BUG_ON() until tdx_handle_exit() because this is in
* non-instrumentable code with interrupts disabled.
*/
- return TDX_INVALID_EXIT_REASON;
+ exit_reason.basic = TDX_INVALID_EXIT_REASON;
+ break;
default:
break;
}
@@ -981,7 +985,7 @@ static noinstr void tdx_vcpu_enter_exit(struct kvm_vcpu *vcpu)
tdx->vp_enter_ret = tdh_vp_enter(&tdx->vp, &tdx->vp_enter_args);
- vt->exit_reason.full = tdx_to_vmx_exit_reason(vcpu);
+ vt->exit_reason = tdx_to_vmx_exit_reason(vcpu);
vt->exit_qualification = tdx->vp_enter_args.rcx;
tdx->ext_exit_qualification = tdx->vp_enter_args.rdx;
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 5/9] KVM: TDX: Update exit_reason on wait_for_sept_zap return
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
` (3 preceding siblings ...)
2026-08-19 9:48 ` [PATCH v4 4/9] KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason() Xiaoyao Li
@ 2026-08-19 9:48 ` Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 6/9] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected Xiaoyao Li
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:48 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
Update exit_reason to a value with bit[31:16] cleared and bit[15:0]
set to TDX_INVALID_EXIT_REASON when it needs to return early due to
wait_for_sept_zap in tdx_vcpu_run(). This avoids the stale exit_reason
of the previous Exit being consumed twice.
Fixes: 4b2abc49712b ("KVM: TDX: Kick off vCPUs when SEAMCALL is busy during TD page removal")
Cc: stable@vger.kernel.org
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
Changes in v4:
- new patch;
---
arch/x86/kvm/vmx/tdx.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 987092283955..014710945e8a 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1088,8 +1088,21 @@ 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))) {
+ /*
+ * The vCPU never entered the guest, but this looks like a
+ * handled exit to the caller. Synthesize an invalid exit
+ * reason so the previous exit's stale value isn't consumed
+ * a second time.
+ *
+ * Make it super clear that bit[31:16] is cleared to 0 and only
+ * basic exit reason (bit[15:0]) is set to the synthesized
+ * invalid exit reason.
+ */
+ vt->exit_reason.full = 0;
+ vt->exit_reason.basic = TDX_INVALID_EXIT_REASON;
return EXIT_FASTPATH_EXIT_HANDLED;
+ }
trace_kvm_entry(vcpu, run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT);
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 6/9] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
` (4 preceding siblings ...)
2026-08-19 9:48 ` [PATCH v4 5/9] KVM: TDX: Update exit_reason on wait_for_sept_zap return Xiaoyao Li
@ 2026-08-19 9:49 ` Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 7/9] KVM: VMX: Make handle_bus_lock_vmexit() a shared helper Xiaoyao Li
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:49 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
Preserve the negative return value from __vmx_handle_exit() when a bus
lock is detected, instead of always overwriting it with 0.
The purpose of bus_lock_detected handling is to force a userspace exit to
inform userspace that a bus lock happened. The negative return value can
achieve this purpose, and changing the negative value to 0 fails to return
an error to userspace. So, preserve the negative return value.
Fixes: fe6b6bc802b4 ("KVM: VMX: Enable bus lock VM exit")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/all/20260805034602.5B2BB1F000E9@smtp.kernel.org/
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
I'm not sure on the Closes: link, since Sashiko didn't find the VMX
issue directly.
Changes in v4
- grabbed from https://lore.kernel.org/all/20260806111923.1990562-2-xiaoyao.li@intel.com/
---
arch/x86/kvm/vmx/vmx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 35ac9ddffaf4..d302d0ce47f1 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6860,11 +6860,12 @@ int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
* a bus lock in guest.
*/
if (vmx_get_exit_reason(vcpu).bus_lock_detected) {
- if (ret > 0)
+ if (ret > 0) {
vcpu->run->exit_reason = KVM_EXIT_X86_BUS_LOCK;
+ ret = 0;
+ }
vcpu->run->flags |= KVM_RUN_X86_BUS_LOCK;
- return 0;
}
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 7/9] KVM: VMX: Make handle_bus_lock_vmexit() a shared helper
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
` (5 preceding siblings ...)
2026-08-19 9:49 ` [PATCH v4 6/9] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected Xiaoyao Li
@ 2026-08-19 9:49 ` Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 8/9] KVM: TDX: Enable Bus Lock VM exit Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 9/9] KVM: VMX: Consolidate the exit handler for VMX and TDX Xiaoyao Li
8 siblings, 0 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:49 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
Move handle_bus_lock_vmexit() from vmx.c to main.c to make it a shared
helper so that TDX can use it for Bus Lock VM exit handling as well.
Rename it to add vt_ prefix to reflect that it is a helper for both VMX
and TDX.
Cc: stable@vger.kernel.org
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
Changes in v4:
- split from next patch
---
arch/x86/kvm/vmx/common.h | 1 +
arch/x86/kvm/vmx/main.c | 11 +++++++++++
arch/x86/kvm/vmx/vmx.c | 13 +------------
3 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h
index 7fce1bbabc78..bbeec197a507 100644
--- a/arch/x86/kvm/vmx/common.h
+++ b/arch/x86/kvm/vmx/common.h
@@ -203,5 +203,6 @@ static inline int __vt_handle_notify(struct kvm_vcpu *vcpu,
}
noinstr void vmx_handle_nmi(struct kvm_vcpu *vcpu);
+int vt_handle_bus_lock_vmexit(struct kvm_vcpu *vcpu);
#endif /* __KVM_X86_VMX_COMMON_H */
diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c
index 0ff3230fd95e..6a813c49ca8a 100644
--- a/arch/x86/kvm/vmx/main.c
+++ b/arch/x86/kvm/vmx/main.c
@@ -876,6 +876,17 @@ static int vt_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn,
#define vt_op_tdx_only(name) NULL
#endif /* CONFIG_KVM_INTEL_TDX */
+int vt_handle_bus_lock_vmexit(struct kvm_vcpu *vcpu)
+{
+ /*
+ * Hardware may or may not set the BUS_LOCK_DETECTED flag on BUS_LOCK
+ * VM-Exits. Unconditionally set the flag here and leave the handling
+ * to .handle_exit() callback.
+ */
+ to_vt(vcpu)->exit_reason.bus_lock_detected = true;
+ return 1;
+}
+
#define VMX_REQUIRED_APICV_INHIBITS \
(BIT(APICV_INHIBIT_REASON_DISABLED) | \
BIT(APICV_INHIBIT_REASON_ABSENT) | \
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index d302d0ce47f1..58c001b6cbc5 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6265,17 +6265,6 @@ static int handle_encls(struct kvm_vcpu *vcpu)
}
#endif /* CONFIG_X86_SGX_KVM */
-static int handle_bus_lock_vmexit(struct kvm_vcpu *vcpu)
-{
- /*
- * Hardware may or may not set the BUS_LOCK_DETECTED flag on BUS_LOCK
- * VM-Exits. Unconditionally set the flag here and leave the handling to
- * vmx_handle_exit().
- */
- to_vt(vcpu)->exit_reason.bus_lock_detected = true;
- return 1;
-}
-
static int handle_notify(struct kvm_vcpu *vcpu)
{
unsigned long exit_qual = vmx_get_exit_qual(vcpu);
@@ -6364,7 +6353,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[EXIT_REASON_VMFUNC] = handle_vmx_instruction,
[EXIT_REASON_PREEMPTION_TIMER] = handle_preemption_timer,
[EXIT_REASON_ENCLS] = handle_encls,
- [EXIT_REASON_BUS_LOCK] = handle_bus_lock_vmexit,
+ [EXIT_REASON_BUS_LOCK] = vt_handle_bus_lock_vmexit,
[EXIT_REASON_NOTIFY] = handle_notify,
[EXIT_REASON_SEAMCALL] = handle_tdx_instruction,
[EXIT_REASON_TDCALL] = handle_tdx_instruction,
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 8/9] KVM: TDX: Enable Bus Lock VM exit
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
` (6 preceding siblings ...)
2026-08-19 9:49 ` [PATCH v4 7/9] KVM: VMX: Make handle_bus_lock_vmexit() a shared helper Xiaoyao Li
@ 2026-08-19 9:49 ` Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 9/9] KVM: VMX: Consolidate the exit handler for VMX and TDX Xiaoyao Li
8 siblings, 0 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:49 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
Enable Bus Lock VM exit functionality for TDX guests.
Bus Lock VM exit is an existing feature supported by KVM. Userspace can
enable Bus Lock VM exit through KVM_BUS_LOCK_DETECTION_EXIT when it's
reported as supported. However, KVM reports the support of this CAP
just based on the hardware capability but doesn't differentiate between
VMX and TDX. This leads to the issue that userspace can enable this cap
for TDX guests without getting an error, but the feature is not actually
enabled because KVM doesn't call the TDX module API to program the
relevant TD VMCS fields.
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.
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@vger.kernel.org
Originally-by: Chenyi Qiang <chenyi.qiang@intel.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
Changes in 4:
- The code to make handle_bus_lock_vmexit() a shared helper is split
as a separate patch.
- The handling for wait_for_sept_zap is no longer needed since a general
handling for it is added as a separate patch.
Changes in v3:
- Refine the changelog. (Rick)
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.
---
arch/x86/kvm/vmx/tdx.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 014710945e8a..8db0c67aaadc 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -2058,7 +2058,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;
@@ -2159,6 +2159,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 __vt_handle_notify(vcpu, vmx_get_exit_qual(vcpu));
+ case EXIT_REASON_BUS_LOCK:
+ return vt_handle_bus_lock_vmexit(vcpu);
default:
break;
}
@@ -2168,6 +2170,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;
+}
+
void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
u64 *info1, u64 *info2, u32 *intr_info, u32 *error_code)
{
@@ -3194,6 +3212,10 @@ static int tdx_vcpu_init(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *cmd)
vcpu->kvm->arch.notify_window);
}
+ if (vcpu->kvm->arch.bus_lock_detection_enabled)
+ td_vmcs_setbit32(tdx, SECONDARY_VM_EXEC_CONTROL,
+ SECONDARY_EXEC_BUS_LOCK_DETECTION);
+
tdx->state = VCPU_TD_STATE_INITIALIZED;
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 9/9] KVM: VMX: Consolidate the exit handler for VMX and TDX
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
` (7 preceding siblings ...)
2026-08-19 9:49 ` [PATCH v4 8/9] KVM: TDX: Enable Bus Lock VM exit Xiaoyao Li
@ 2026-08-19 9:49 ` Xiaoyao Li
8 siblings, 0 replies; 11+ messages in thread
From: Xiaoyao Li @ 2026-08-19 9:49 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Kiryl Shutsemau, Rick Edgecombe, Xiaoyao Li, kvm, linux-kernel,
linux-coco, nik.borisov
The exit handlers for VMX and TDX have the similar pattern. Consolidate
them into a single vt_handle_exit() helper.
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Changes in v4:
- new patch.
---
arch/x86/kvm/vmx/main.c | 38 ++++++++++++++++++++++++++++----------
arch/x86/kvm/vmx/tdx.c | 18 +-----------------
arch/x86/kvm/vmx/vmx.c | 21 +--------------------
3 files changed, 30 insertions(+), 47 deletions(-)
diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c
index 6a813c49ca8a..10df9667d0c0 100644
--- a/arch/x86/kvm/vmx/main.c
+++ b/arch/x86/kvm/vmx/main.c
@@ -154,15 +154,6 @@ static fastpath_t vt_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
return vmx_vcpu_run(vcpu, run_flags);
}
-static int vt_handle_exit(struct kvm_vcpu *vcpu,
- enum exit_fastpath_completion fastpath)
-{
- if (is_td_vcpu(vcpu))
- return tdx_handle_exit(vcpu, fastpath);
-
- return vmx_handle_exit(vcpu, fastpath);
-}
-
static bool vt_unhandleable_emulation_required(struct kvm_vcpu *vcpu)
{
if (is_td_vcpu(vcpu)) {
@@ -887,6 +878,33 @@ int vt_handle_bus_lock_vmexit(struct kvm_vcpu *vcpu)
return 1;
}
+static int vt_handle_exit(struct kvm_vcpu *vcpu,
+ enum exit_fastpath_completion fastpath)
+{
+ int ret;
+
+#ifdef CONFIG_KVM_INTEL_TDX
+ if (is_td_vcpu(vcpu))
+ ret = tdx_handle_exit(vcpu, fastpath);
+ else
+#endif
+ ret = vmx_handle_exit(vcpu, fastpath);
+
+ /*
+ * Exit to user space when bus lock detected to inform that there is
+ * a bus lock in guest.
+ */
+ 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;
+}
+
#define VMX_REQUIRED_APICV_INHIBITS \
(BIT(APICV_INHIBIT_REASON_DISABLED) | \
BIT(APICV_INHIBIT_REASON_ABSENT) | \
@@ -960,7 +978,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
.vcpu_needs_initialization = vt_op_tdx_only(vcpu_needs_initialization),
.vcpu_run = vt_op(vcpu_run),
- .handle_exit = vt_op(handle_exit),
+ .handle_exit = vt_handle_exit,
.skip_emulated_instruction = vmx_skip_emulated_instruction,
.update_emulated_instruction = vmx_update_emulated_instruction,
.unhandleable_emulation_required = vt_op(unhandleable_emulation_required),
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 8db0c67aaadc..364a2322a9f5 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -2058,7 +2058,7 @@ int tdx_complete_emulated_msr(struct kvm_vcpu *vcpu, int err)
}
-static int __tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
+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;
@@ -2170,22 +2170,6 @@ static 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;
-}
-
void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
u64 *info1, u64 *info2, u32 *intr_info, u32 *error_code)
{
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 58c001b6cbc5..490baae56cf1 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6681,7 +6681,7 @@ void dump_vmcs(struct kvm_vcpu *vcpu)
* The guest has exited. See if we can fix it or if we need userspace
* assistance.
*/
-static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
+int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
union vmx_exit_reason exit_reason = vmx_get_exit_reason(vcpu);
@@ -6840,25 +6840,6 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
return 0;
}
-int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
-{
- int ret = __vmx_handle_exit(vcpu, exit_fastpath);
-
- /*
- * Exit to user space when bus lock detected to inform that there is
- * a bus lock in guest.
- */
- 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;
-}
-
void vmx_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
{
int tpr_threshold;
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 4/9] KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason()
2026-08-19 9:48 ` [PATCH v4 4/9] KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason() Xiaoyao Li
@ 2026-08-19 10:16 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-19 10:16 UTC (permalink / raw)
To: Xiaoyao Li; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Medium] Strict equality checks on the raw 64-bit `vp_enter_ret` fail when Bus Lock VM exit sets bit 26, bypassing the intended `KVM_BUG_ON()` and fastpath logic.
--
--- Patch [4]: [PATCH v4 4/9] KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason() ---
commit 48df7e5971adbfae6378e9f4d893dc4fe8eb125f
Author: Xiaoyao Li <xiaoyao.li@intel.com>
KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason()
This commit changes tdx_to_vmx_exit_reason() to handle the upper 16 bits
of the exit reason instead of assuming they are all zero. It changes the
return type to union vmx_exit_reason to make manipulating the basic field
more convenient while preserving the upper bits for when Bus Lock VM exit
is enabled.
> diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
> index 4e275cb6927ad..9870922839552 100644
> --- a/arch/x86/kvm/vmx/tdx.c
> +++ b/arch/x86/kvm/vmx/tdx.c
[ ... ]
> @@ -949,22 +949,26 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
> * but this is NOT a failed VM-Enter.
> */
> if (!tdx_is_exit_reason_valid(tdx->vp_enter_ret))
> - return TDX_INVALID_EXIT_REASON;
> + return (union vmx_exit_reason) {
> + .basic = TDX_INVALID_EXIT_REASON,
> + };
>
> - exit_reason = tdx->vp_enter_ret;
> + exit_reason.full = (u32)tdx->vp_enter_ret;
>
> - switch (exit_reason) {
> + switch (exit_reason.basic) {
> case EXIT_REASON_TDCALL:
> if (tdvmcall_exit_type(vcpu))
> - return EXIT_REASON_VMCALL;
> -
> - return tdcall_to_vmx_exit_reason(vcpu);
> + exit_reason.basic = EXIT_REASON_VMCALL;
> + else
> + exit_reason.basic = tdcall_to_vmx_exit_reason(vcpu);
> + break;
> case EXIT_REASON_EPT_MISCONFIG:
> /*
> * Defer KVM_BUG_ON() until tdx_handle_exit() because this is in
> * non-instrumentable code with interrupts disabled.
> */
> - return TDX_INVALID_EXIT_REASON;
> + exit_reason.basic = TDX_INVALID_EXIT_REASON;
> + break;
[Severity: Medium]
This is a pre-existing issue, but since we are preparing for Bus Lock VM exits
which can set bit 26 in the exit reason, will the deferred checks in other
functions still work correctly?
Looking at tdx_handle_exit() in arch/x86/kvm/vmx/tdx.c, it checks the raw
vp_enter_ret directly against EXIT_REASON_EPT_MISCONFIG:
if (unlikely(vp_enter_ret == EXIT_REASON_EPT_MISCONFIG)) {
KVM_BUG_ON(1, vcpu->kvm);
return -EIO;
}
Similarly, tdx_vcpu_run() also performs a strict equality check:
if (unlikely(tdx->vp_enter_ret == EXIT_REASON_EPT_MISCONFIG))
return EXIT_FASTPATH_NONE;
If a bus lock VM exit occurs concurrently with an EPT misconfig, setting bit
26 in vp_enter_ret, won't these strict equality checks fail and bypass the
intended bug-handling paths? Should these checks be updated to mask the upper
bits or use the basic exit reason before enabling Bus Lock VM exit?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260819094903.3060020-1-xiaoyao.li@intel.com?part=4
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-08-19 10:16 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-19 9:48 [PATCH v4 0/9] KVM: TDX: Enable VM-DoS Prevention Features for TDX Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 1/9] KVM: TDX: Enable Notify VM exit Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 2/9] KVM: TDX: Check if there is valid exit infos based on vp_enter_ret Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 3/9] KVM: TDX: Set bits 31:16 to 0 for the synthesized Exit Reason Xiaoyao Li
2026-08-19 9:48 ` [PATCH v4 4/9] KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason() Xiaoyao Li
2026-08-19 10:16 ` sashiko-bot
2026-08-19 9:48 ` [PATCH v4 5/9] KVM: TDX: Update exit_reason on wait_for_sept_zap return Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 6/9] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 7/9] KVM: VMX: Make handle_bus_lock_vmexit() a shared helper Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 8/9] KVM: TDX: Enable Bus Lock VM exit Xiaoyao Li
2026-08-19 9:49 ` [PATCH v4 9/9] KVM: VMX: Consolidate the exit handler for VMX and TDX Xiaoyao Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox