Re: [RFC PATCH v1] x86/split_lock: Provide KVM helper to log guest bus lock exits

Borislav Petkov
2026-03-24T18:05:33Z

On Tue, Mar 24, 2026 at 12:40:02PM +0000, Manali Shukla wrote:
> Bus locks monopolize the memory bus for thousands of cycles, stalling
> all CPUs and degrading system performance for every workload on the
> system. Cloud providers running multiple VMs need a way to identify
> which guest is responsible, so the offending VM can be flagged.
>
> Bus lock VMEXITs on AMD are fault-style, i.e. the vCPU's RIP points to
> the offending instruction at the time of the exit. Log guest's linear
> RIP and vCPU info to give operators the data needed to attribute the bus
> lock to a specific VM and instruction. Keep policy enforcement to
> userspace via KVM_EXIT_X86_BUS_LOCK and let userspace implement
> throttling or other mitigations.
>
> Reuse current->reported_split_lock to limit the warning to the once per

s/ to the once/ to once/

> vCPU thread. Note that, current->reported_split_lock tracks the vCPU
> thread, not the individual guest process, i.e. the warning fires once
> per vCPU for the lifetime of thread regardless of how many distinct

"... for the lifetime of the thread... "

> guest processes trigger bus locks on that vCPU.

I guess that's fine since you're ratelimited.

>
> ----

What's that "----" supposed to denote here?

> The intent is purely observational — give hypervisor owners
> visibility into which guest is generating bus locks so they can act
> accordingly. No policy enforcement is done in the kernel. Suggestions
> on the approach are welcome.

Oh, sounds like you want this paragraph to be...

>
> Suggested-by: Nikunj A Dadhania <nikunj@amd.com>
> Signed-off-by: Manali Shukla <manali.shukla@amd.com>
> ---

<--- ... here, after the SOB block and above the diffstat.

> arch/x86/include/asm/cpu.h | 2 ++
> arch/x86/kernel/cpu/bus_lock.c | 19 +++++++++++++++++++
> arch/x86/kvm/svm/svm.c | 1 +
> 3 files changed, 22 insertions(+)
>
> diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
> index ad235dda1ded..4ac5011e10b2 100644
> --- a/arch/x86/include/asm/cpu.h
> +++ b/arch/x86/include/asm/cpu.h
> @@ -29,6 +29,7 @@ unsigned int x86_stepping(unsigned int sig);
> extern void __init sld_setup(struct cpuinfo_x86 *c);
> extern bool handle_user_split_lock(struct pt_regs *regs, long error_code);
> extern bool handle_guest_split_lock(unsigned long ip);
> +extern void handle_guest_bus_lock(unsigned long ip);
> extern void handle_bus_lock(struct pt_regs *regs);
> void split_lock_init(void);
> void bus_lock_init(void);
> @@ -44,6 +45,7 @@ static inline bool handle_guest_split_lock(unsigned long ip)
> return false;
> }
>
> +static inline void handle_guest_bus_lock(unsigned long ip) {}
> static inline void handle_bus_lock(struct pt_regs *regs) {}
> static inline void split_lock_init(void) {}
> static inline void bus_lock_init(void) {}
> diff --git a/arch/x86/kernel/cpu/bus_lock.c b/arch/x86/kernel/cpu/bus_lock.c
> index fb166662bc0d..a6d231410535 100644
> --- a/arch/x86/kernel/cpu/bus_lock.c
> +++ b/arch/x86/kernel/cpu/bus_lock.c
> @@ -292,6 +292,25 @@ bool handle_guest_split_lock(unsigned long ip)
> }
> EXPORT_SYMBOL_FOR_KVM(handle_guest_split_lock);
>
> +void handle_guest_bus_lock(unsigned long ip)

Exported function better have a prefix:

bus_lock_guest_handle() or so.

But, the only reason this function is here is because you need sld_state.

So, instead of doing that, you can add a helper called

sld_enabled()

or so, which is exported and then you can put the guest-specific handling in
svm.c in case you want to expand it in the future and there you use
sld_enabled(), etc...

> +{
> + /*
> + * Log bus lock exit when called from KVM exit handlers. Policy
> + * enforcement is delegated to userspace via KVM_EXIT_X86_BUS_LOCK.
> + * Let userspace implement throttling or other mitigations.
> + *
> + * Only log when split lock detection is active to respect system-wide
> + * bus lock detection policy. Use the reported_split_lock flag to
> + * prevent log spam from the same vCPU.
> + */
> + if (sld_state != sld_off && !current->reported_split_lock) {
> + pr_warn_ratelimited("%s/%d buslock at rip: 0x%lx\n",
> + current->comm, current->pid, ip);
> + current->reported_split_lock = 1;
> + }
> +}
> +EXPORT_SYMBOL_FOR_KVM(handle_guest_bus_lock);

Thx.

--
Regards/Gruss,
Boris.