From: Sean Christopherson <seanjc@google.com>
To: Xiaoyao Li <xiaoyao.li@intel.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/3] KVM: x86: Reject enabling KVM_CAP_X86_BUS_LOCK_EXIT when !kvm_caps.has_bus_lock_exit
Date: Thu, 6 Aug 2026 07:31:00 -0700 [thread overview]
Message-ID: <anSapM1jrwRkojQs@google.com> (raw)
In-Reply-To: <20260806111923.1990562-3-xiaoyao.li@intel.com>
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
>
next prev parent reply other threads:[~2026-08-06 14:31 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
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:35 ` sashiko-bot
2026-08-07 1:27 ` Xiaoyao Li
2026-08-06 14:31 ` Sean Christopherson [this message]
2026-08-06 11:19 ` [PATCH 3/3] KVM: x86: Only allow enabling KVM_BUS_LOCK_DETECTION_EXIT before creating any vCPU Xiaoyao Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=anSapM1jrwRkojQs@google.com \
--to=seanjc@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=xiaoyao.li@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox