The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH 0/3] KVM: x86: BUS_LOCK_EXIT fixes
@ 2026-08-06 11:19 Xiaoyao Li
  2026-08-06 11:19 ` [PATCH 1/3] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected Xiaoyao Li
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Xiaoyao Li @ 2026-08-06 11:19 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, xiaoyao.li

This series contains fixes for x86 Bus Lock Exit feature.

Patch 1 fixes a bug which is somewhat discovered by Sashiko, when it
reviewed the TDX Bus Lock Exit enabling patch [1]. It pointed out one
issue for the TDX patch, and I found the existing VMX code has the same
issue.

Patch 2 and patch 3 fix the issues for KVM_CAP_X86_BUS_LOCK_EXIT,
which were found When I tested the TDX Bus Lock Exit enabling patch.

[1] https://lore.kernel.org/all/20260805034602.5B2BB1F000E9@smtp.kernel.org/

Xiaoyao Li (3):
  KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus
    lock detected
  KVM: x86: Reject enabling KVM_CAP_X86_BUS_LOCK_EXIT when
    !kvm_caps.has_bus_lock_exit
  KVM: x86: Only allow enabling KVM_BUS_LOCK_DETECTION_EXIT before
    creating any vCPU

 arch/x86/kvm/vmx/vmx.c |  5 +++--
 arch/x86/kvm/x86.c     | 14 +++++++++++---
 2 files changed, 14 insertions(+), 5 deletions(-)


base-commit: a806d364ef288a6443a1337820ea8410a7ccc6b3
-- 
2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected
  2026-08-06 11:19 [PATCH 0/3] KVM: x86: BUS_LOCK_EXIT fixes Xiaoyao Li
@ 2026-08-06 11:19 ` Xiaoyao Li
  2026-08-06 11:19 ` [PATCH 2/3] KVM: x86: Reject enabling KVM_CAP_X86_BUS_LOCK_EXIT when !kvm_caps.has_bus_lock_exit Xiaoyao Li
  2026-08-06 11:19 ` [PATCH 3/3] KVM: x86: Only allow enabling KVM_BUS_LOCK_DETECTION_EXIT before creating any vCPU Xiaoyao Li
  2 siblings, 0 replies; 5+ messages in thread
From: Xiaoyao Li @ 2026-08-06 11:19 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, xiaoyao.li

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")
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.
---
 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 e3bfe6aca1a0..1cd120b5d4a5 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6871,11 +6871,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] 5+ messages in thread

* [PATCH 2/3] KVM: x86: Reject enabling KVM_CAP_X86_BUS_LOCK_EXIT when !kvm_caps.has_bus_lock_exit
  2026-08-06 11:19 [PATCH 0/3] KVM: x86: BUS_LOCK_EXIT fixes Xiaoyao Li
  2026-08-06 11:19 ` [PATCH 1/3] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected Xiaoyao Li
@ 2026-08-06 11:19 ` Xiaoyao Li
  2026-08-06 14:31   ` Sean Christopherson
  2026-08-06 11:19 ` [PATCH 3/3] KVM: x86: Only allow enabling KVM_BUS_LOCK_DETECTION_EXIT before creating any vCPU Xiaoyao Li
  2 siblings, 1 reply; 5+ messages in thread
From: Xiaoyao Li @ 2026-08-06 11:19 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, xiaoyao.li

Return -EINVAL to reject the enabling of KVM_CAP_X86_BUS_LOCK_EXIT from
userspace when kvm_caps.has_bus_lock_exit is false.

For KVM_BUS_LOCK_DETECTION_EXIT, if KVM doesn't support BUS LOCK EXIT,
return error to userspace instead of success.

For KVM_BUS_LOCK_DETECTION_OFF, it seems OK to allow it when KVM doesn't
support bus_lock_exit. But from an API perspective, it implies
inconsistency that KVM_CAP_X86_BUS_LOCK_EXIT reports 0 but setting
KVM_BUS_LOCK_DETECTION_OFF is allowed. To keep it consistent, also
return error for KVM_BUS_LOCK_DETECTION_OFF when KVM doesn't support
BUS LOCK EXIT.

Fixes: fe6b6bc802b4 ("KVM: VMX: Enable bus lock VM exit")
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
---
 arch/x86/kvm/x86.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d94b59140c45..3d8422d1cd04 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4058,8 +4058,10 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 		    (cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT))
 			break;
 
-		if (kvm_caps.has_bus_lock_exit &&
-		    cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT)
+		if (!kvm_caps.has_bus_lock_exit)
+			break;
+
+		if (cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT)
 			kvm->arch.bus_lock_detection_enabled = true;
 		r = 0;
 		break;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] KVM: x86: Only allow enabling KVM_BUS_LOCK_DETECTION_EXIT before creating any vCPU
  2026-08-06 11:19 [PATCH 0/3] KVM: x86: BUS_LOCK_EXIT fixes Xiaoyao Li
  2026-08-06 11:19 ` [PATCH 1/3] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected Xiaoyao Li
  2026-08-06 11:19 ` [PATCH 2/3] KVM: x86: Reject enabling KVM_CAP_X86_BUS_LOCK_EXIT when !kvm_caps.has_bus_lock_exit Xiaoyao Li
@ 2026-08-06 11:19 ` Xiaoyao Li
  2 siblings, 0 replies; 5+ messages in thread
From: Xiaoyao Li @ 2026-08-06 11:19 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, xiaoyao.li

When userspace enables KVM_BUS_LOCK_DETECTION_EXIT after some vCPUs have
been created, KVM may fail to enable the feature for created vCPUs. It
is possible for KVM to later enable the feature for created vCPUs in some
cases, but it's not guaranteed. Instead of introducing complexity to support
this use case, just disallow enabling KVM_BUS_LOCK_DETECTION_EXIT when
vCPUs have been created for simplicity.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 arch/x86/kvm/x86.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3d8422d1cd04..df8ee03cd9ad 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4061,9 +4061,15 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 		if (!kvm_caps.has_bus_lock_exit)
 			break;
 
-		if (cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT)
-			kvm->arch.bus_lock_detection_enabled = true;
 		r = 0;
+		if (cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT) {
+			mutex_lock(&kvm->lock);
+			if (!kvm->created_vcpus)
+				kvm->arch.bus_lock_detection_enabled = true;
+			else
+				r = -EINVAL;
+			mutex_unlock(&kvm->lock);
+		}
 		break;
 #ifdef CONFIG_X86_SGX_KVM
 	case KVM_CAP_SGX_ATTRIBUTE: {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] KVM: x86: Reject enabling KVM_CAP_X86_BUS_LOCK_EXIT when !kvm_caps.has_bus_lock_exit
  2026-08-06 11:19 ` [PATCH 2/3] KVM: x86: Reject enabling KVM_CAP_X86_BUS_LOCK_EXIT when !kvm_caps.has_bus_lock_exit Xiaoyao Li
@ 2026-08-06 14:31   ` Sean Christopherson
  0 siblings, 0 replies; 5+ messages in thread
From: Sean Christopherson @ 2026-08-06 14:31 UTC (permalink / raw)
  To: Xiaoyao Li; +Cc: Paolo Bonzini, kvm, linux-kernel

On Thu, Aug 06, 2026, Xiaoyao Li wrote:
> Return -EINVAL to reject the enabling of KVM_CAP_X86_BUS_LOCK_EXIT from
> userspace when kvm_caps.has_bus_lock_exit is false.
> 
> For KVM_BUS_LOCK_DETECTION_EXIT, if KVM doesn't support BUS LOCK EXIT,
> return error to userspace instead of success.
> 
> For KVM_BUS_LOCK_DETECTION_OFF, it seems OK to allow it when KVM doesn't
> support bus_lock_exit. But from an API perspective, it implies
> inconsistency that KVM_CAP_X86_BUS_LOCK_EXIT reports 0 but setting
> KVM_BUS_LOCK_DETECTION_OFF is allowed. To keep it consistent, also
> return error for KVM_BUS_LOCK_DETECTION_OFF when KVM doesn't support
> BUS LOCK EXIT.
> 
> Fixes: fe6b6bc802b4 ("KVM: VMX: Enable bus lock VM exit")
> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
> ---
> ---
>  arch/x86/kvm/x86.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index d94b59140c45..3d8422d1cd04 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -4058,8 +4058,10 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
>  		    (cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT))
>  			break;
>  
> -		if (kvm_caps.has_bus_lock_exit &&
> -		    cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT)
> +		if (!kvm_caps.has_bus_lock_exit)
> +			break;

Yikes, we really botched this one.

KVM unfortunately made KVM_BUS_LOCK_DETECTION_OFF an explicit flag, not an absense
of flags, without actually honoring that flag.  E.g. doing KVM_BUS_LOCK_DETECTION_OFF
after KVM_BUS_LOCK_DETECTION_EXIT doesn't actually turn off detection.

I vote to get greedy and try dropping KVM_BUS_LOCK_DETECTION_OFF entirely, and
making it so that calling the CAP without any flags turns off detection.  Otherwise
we have to either rejec that case (also risks breaking userspace) or treat it as
"do nothing" (which is just stupid).  We'd want to reserve bit 0 to avoid really
bad breakage, i.e. so that we don't re-introduce bit 0 as something else, but
that's easy enough.

I'm thinking this over a few patches:

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 1e64026d7c1e..b7c21675aa81 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -8379,7 +8379,6 @@ The valid mask flags are:
 
 Valid bits in args[0] are::
 
-  #define KVM_BUS_LOCK_DETECTION_OFF      (1 << 0)
   #define KVM_BUS_LOCK_DETECTION_EXIT     (1 << 1)
 
 Enabling this capability on a VM provides userspace with a way to select a
@@ -8393,8 +8392,8 @@ guest, irrespective whether or not the host has enabled split-lock detection
 intended to mitigate attacks where a malicious/buggy guest can exploit bus
 locks to degrade the performance of the whole system.
 
-If KVM_BUS_LOCK_DETECTION_OFF is set, KVM doesn't force guest bus locks to VM
-exit, although the host kernel's split-lock #AC detection still applies, if
+If KVM_BUS_LOCK_DETECTION_EXIT is not set, KVM doesn't force guest bus locks to
+VM exit, although the host kernel's split-lock #AC detection still applies, if
 enabled.
 
 If KVM_BUS_LOCK_DETECTION_EXIT is set, KVM enables a CPU feature that ensures
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1ac60628b4c0..67791d139615 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -150,8 +150,8 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_host);
        (KVM_X86_QUIRK_CD_NW_CLEARED |          \
         KVM_X86_QUIRK_IGNORE_GUEST_PAT)
 
-#define KVM_BUS_LOCK_DETECTION_VALID_MODE      (KVM_BUS_LOCK_DETECTION_OFF | \
-                                                KVM_BUS_LOCK_DETECTION_EXIT)
+/* Bit 0 is forever reserved to avoid breaking userspace in bad ways. */
+#define KVM_BUS_LOCK_DETECTION_VALID_MASK      (KVM_BUS_LOCK_DETECTION_EXIT & ~BIT(0))
 
 #define KVM_X86_NOTIFY_VMEXIT_VALID_BITS       (KVM_X86_NOTIFY_VMEXIT_ENABLED | \
                                                 KVM_X86_NOTIFY_VMEXIT_USER)
@@ -2381,8 +2381,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                break;
        case KVM_CAP_X86_BUS_LOCK_EXIT:
                if (kvm_caps.has_bus_lock_exit)
-                       r = KVM_BUS_LOCK_DETECTION_OFF |
-                           KVM_BUS_LOCK_DETECTION_EXIT;
+                       r = KVM_BUS_LOCK_DETECTION_VALID_MASK;
                else
                        r = 0;
                break;
@@ -4051,17 +4050,18 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
                break;
        case KVM_CAP_X86_BUS_LOCK_EXIT:
                r = -EINVAL;
-               if (cap->args[0] & ~KVM_BUS_LOCK_DETECTION_VALID_MODE)
+               if (!kvm_caps.has_bus_lock_exit)
                        break;
 
-               if ((cap->args[0] & KVM_BUS_LOCK_DETECTION_OFF) &&
-                   (cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT))
+               if (cap->args[0] & ~KVM_BUS_LOCK_DETECTION_VALID_MASK)
                        break;
 
-               if (kvm_caps.has_bus_lock_exit &&
-                   cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT)
-                       kvm->arch.bus_lock_detection_enabled = true;
-               r = 0;
+               mutex_lock(&kvm->lock);
+               if (!kvm->created_vcpus) {
+                       kvm->arch.bus_lock_detection_enabled = cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT;
+                       r = 0;
+               }
+               mutex_unlock(&kvm->lock);
                break;
 #ifdef CONFIG_X86_SGX_KVM
        case KVM_CAP_SGX_ATTRIBUTE: {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 129d6f630325..08e5fe09e5c8 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1542,7 +1542,6 @@ struct kvm_dirty_gfn {
        __u64 offset;
 };
 
-#define KVM_BUS_LOCK_DETECTION_OFF             (1 << 0)
 #define KVM_BUS_LOCK_DETECTION_EXIT            (1 << 1)
 
 #define KVM_PMU_CAP_DISABLE                    (1 << 0)


> +
> +		if (cap->args[0] & KVM_BUS_LOCK_DETECTION_EXIT)
>  			kvm->arch.bus_lock_detection_enabled = true;
>  		r = 0;
>  		break;
> -- 
> 2.43.0
> 

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-08-06 14:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-06 11:19 [PATCH 0/3] KVM: x86: BUS_LOCK_EXIT fixes Xiaoyao Li
2026-08-06 11:19 ` [PATCH 1/3] KVM: VMX: Preserve negative return value in vmx_handle_exit() with bus lock detected Xiaoyao Li
2026-08-06 11:19 ` [PATCH 2/3] KVM: x86: Reject enabling KVM_CAP_X86_BUS_LOCK_EXIT when !kvm_caps.has_bus_lock_exit Xiaoyao Li
2026-08-06 14:31   ` Sean Christopherson
2026-08-06 11:19 ` [PATCH 3/3] KVM: x86: Only allow enabling KVM_BUS_LOCK_DETECTION_EXIT before creating any vCPU Xiaoyao Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox