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

Manali Shukla
2026-03-25T09:32:41Z

On 3/24/2026 11:34 PM, Borislav Petkov wrote:
> 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.

Oh, my bad. will correct in v2.

>
>> 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...
>

Thank you for your suggestion, will fix the naming in v2.
sld_enabled() could be added in bus_lock.c and called from
bus_lock_exit() in svm.c. However, the other reason for keeping the
function in bus_lock.c is the current->reported_split_lock usage - it is
already used in split_lock_warn() and handle_guest_split_lock() in the
same file, so keeping all reported_split_lock accesses in bus_lock.c
seemed more maintainable. But happy to move it to svm.c, if you prefer
that approach.

>> +{
>> + /*
>> + * 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.
>

-Manali