x86/svm: Intercept Bus Locks for HVM guests

Configure the Bus Lock intercept when supported by hardware (Zen5 and
later). The VMCB counter is initialised to zero so it fires upon the first
instruction that locks the bus. On the #VMEXIT handler that counter is set to
1 because it has fault behaviour and the offending instruction needs to
re-execute.

Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Alejandro Vallejo authored and Andrew Cooper committed 2026-01-22 13:05:39 +00:00
1 parent 06d2514278
commit dd5b8336f5
3 files changed
+22

No files matched your search

+4
View File
@@ -9,6 +9,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Changed
### Added
- On x86:
- Support for Bus Lock Threshold on AMD Zen5 and later CPUs, used by Xen to
mitigate (by rate-limiting) the system wide impact of an HVM guest
misusing atomic instructions.
### Removed
- On x86:
+11
View File
@@ -2524,6 +2524,7 @@ const struct hvm_function_table * __init start_svm(void)
P(cpu_has_tsc_ratio, "TSC Rate MSR");
P(cpu_has_svm_sss, "NPT Supervisor Shadow Stack");
P(cpu_has_svm_spec_ctrl, "MSR_SPEC_CTRL virtualisation");
P(cpu_has_svm_bus_lock, "Bus Lock Filter");
#undef P
if ( !printed )
@@ -3087,6 +3088,16 @@ void asmlinkage svm_vmexit_handler(void)
break;
}
case VMEXIT_BUS_LOCK:
/*
* This is a fault and blocked the Bus Lock inducing action. We're
* only interested in rate limiting the guest, so credit it one "lock"
* in order to re-execute the instruction.
*/
perfc_incr(buslock);
vmcb->bus_lock_count = 1;
break;
default:
unexpected_exit_type:
gprintk(XENLOG_ERR, "Unexpected vmexit: reason %#"PRIx64", "
+7
View File
@@ -66,6 +66,13 @@ static int construct_vmcb(struct vcpu *v)
GENERAL2_INTERCEPT_XSETBV | GENERAL2_INTERCEPT_ICEBP |
GENERAL2_INTERCEPT_RDPRU;
/*
* Well behaved logic shouldn't ever Bus Lock, but we care about rate
* limiting buggy/malicious cases.
*/
if ( cpu_has_svm_bus_lock )
vmcb->_general3_intercepts |= GENERAL3_INTERCEPT_BUS_LOCK;
/* Intercept all debug-register writes. */
vmcb->_dr_intercepts = ~0u;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.