Skip to content

Commit d28565a

Browse files
committed
Add support for bus lock detection
Add support for bus lock detection. The feature can be enabled via KVM_CAP_X86_BUS_LOCK_EXIT, which enables a new exit (KVM_EXIT_X86_BUS_LOCK) and a new flag (KVM_RUN_X86_BUS_LOCK) in the kvm_run->flags field. Add two tests as well to verify that enabling the feature works. Signed-off-by: Carlos López <[email protected]>
1 parent a1d0ef4 commit d28565a

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ reg_size as a public method.
1313
userspace MSR handling.
1414
- [[#246](https://github.com/rust-vmm/kvm-ioctls/pull/246)] Add support for
1515
userspace NMI injection (`KVM_NMI` ioctl).
16+
- [[#245](https://github.com/rust-vmm/kvm-ioctls/pull/245)] x86: add support
17+
for bus lock detection (`KVM_CAP_X86_BUS_LOCK_EXIT` capability).
1618

1719
# v0.15.0
1820

src/cap.rs

+2
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,6 @@ pub enum Cap {
166166
ArmPtrAuthGeneric = KVM_CAP_ARM_PTRAUTH_GENERIC,
167167
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
168168
X86UserSpaceMsr = KVM_CAP_X86_USER_SPACE_MSR,
169+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
170+
X86BusLockExit = KVM_CAP_X86_BUS_LOCK_EXIT,
169171
}

src/ioctls/vcpu.rs

+51
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ pub enum VcpuExit<'a> {
158158
X86Rdmsr(ReadMsrExit<'a>),
159159
/// Corresponds to KVM_EXIT_X86_WRMSR.
160160
X86Wrmsr(WriteMsrExit<'a>),
161+
/// Corresponds to KVM_EXIT_X86_BUS_LOCK.
162+
X86BusLock,
161163
/// Corresponds to an exit reason that is unknown from the current version
162164
/// of the kvm-ioctls crate. Let the consumer decide about what to do with
163165
/// it.
@@ -1544,6 +1546,7 @@ impl VcpuFd {
15441546
Ok(VcpuExit::IoapicEoi(eoi.vector))
15451547
}
15461548
KVM_EXIT_HYPERV => Ok(VcpuExit::Hyperv),
1549+
KVM_EXIT_X86_BUS_LOCK => Ok(VcpuExit::X86BusLock),
15471550
r => Ok(VcpuExit::Unsupported(r)),
15481551
}
15491552
} else {
@@ -1849,6 +1852,19 @@ impl VcpuFd {
18491852
_ => Err(errno::Error::last()),
18501853
}
18511854
}
1855+
1856+
/// If [`Cap::X86BusLockExit`](crate::Cap::X86BusLockExit) was enabled,
1857+
/// checks whether a bus lock was detected on the last VM exit. This may
1858+
/// return `true` even if the corresponding exit was not
1859+
/// [`VcpuExit::X86BusLock`], as a different VM exit may have preempted
1860+
/// it.
1861+
///
1862+
/// See the API documentation for `KVM_CAP_X86_BUS_LOCK_EXIT`.
1863+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
1864+
pub fn bus_lock_detected(&self) -> bool {
1865+
let kvm_run = self.kvm_run_ptr.as_ref();
1866+
kvm_run.flags as u32 & KVM_RUN_X86_BUS_LOCK != 0
1867+
}
18521868
}
18531869

18541870
/// Helper function to create a new `VcpuFd`.
@@ -3075,4 +3091,39 @@ mod tests {
30753091
e => panic!("Unexpected exit: {:?}", e),
30763092
}
30773093
}
3094+
3095+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3096+
#[test]
3097+
fn test_enable_bus_lock_detection() {
3098+
let kvm = Kvm::new().unwrap();
3099+
let vm = kvm.create_vm().unwrap();
3100+
if !vm.check_extension(Cap::X86BusLockExit) {
3101+
return;
3102+
}
3103+
let args = KVM_BUS_LOCK_DETECTION_EXIT;
3104+
let cap = kvm_enable_cap {
3105+
cap: Cap::X86BusLockExit as u32,
3106+
args: [args as u64, 0, 0, 0],
3107+
..Default::default()
3108+
};
3109+
vm.enable_cap(&cap).unwrap();
3110+
}
3111+
3112+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3113+
#[test]
3114+
fn test_enable_bus_lock_detection_invalid() {
3115+
let kvm = Kvm::new().unwrap();
3116+
let vm = kvm.create_vm().unwrap();
3117+
if !vm.check_extension(Cap::X86BusLockExit) {
3118+
return;
3119+
}
3120+
// These flags should be mutually exclusive
3121+
let args = KVM_BUS_LOCK_DETECTION_OFF | KVM_BUS_LOCK_DETECTION_EXIT;
3122+
let cap = kvm_enable_cap {
3123+
cap: Cap::X86BusLockExit as u32,
3124+
args: [args as u64, 0, 0, 0],
3125+
..Default::default()
3126+
};
3127+
vm.enable_cap(&cap).unwrap_err();
3128+
}
30783129
}

0 commit comments

Comments
 (0)