Skip to content

Commit b07d906

Browse files
00xcalxiord
authored andcommitted
Add support for KVM_CAP_X86_SMM / KVM_SMI
Allow VMMs to inject System Management Interrupts (SMIs) into the guest via the KVM_SMI vcpu ioctl, which is available if the KVM_CAP_X86_SMM capability is present. Signed-off-by: Carlos López <carlos.lopez@suse.com>
1 parent 14a08dd commit b07d906

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
## Changed
66
- [[#234](https://github.com/rust-vmm/kvm-ioctls/issues/234)] vcpu: export
77
reg_size as a public method.
8-
-[[#243](https://github.com/rust-vmm/kvm-ioctls/pull/243)] derived the `Copy`
9-
trait for `IoEventAddress` and `NoDatamatch`.
8+
- [[#243](https://github.com/rust-vmm/kvm-ioctls/pull/243)] derived the `Copy`
9+
trait for `IoEventAddress` and `NoDatamatch`.
10+
- [[#242](https://github.com/rust-vmm/kvm-ioctls/pull/242)] x86: add support
11+
for SMI injection via `Vcpu::smi()` (`KVM_SMI` ioctl).
1012

1113
# v0.15.0
1214

src/cap.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ pub enum Cap {
146146
CheckExtensionVm = KVM_CAP_CHECK_EXTENSION_VM,
147147
S390UserSigp = KVM_CAP_S390_USER_SIGP,
148148
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
149+
X86Smm = KVM_CAP_X86_SMM,
150+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
149151
SplitIrqchip = KVM_CAP_SPLIT_IRQCHIP,
150152
ArmPmuV3 = KVM_CAP_ARM_PMU_V3,
151153
ImmediateExit = KVM_CAP_IMMEDIATE_EXIT,

src/ioctls/vcpu.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,29 @@ impl VcpuFd {
17201720
// `get_vcpu_map_size`, so this region is in bounds
17211721
unsafe { &mut kvm_run.s.regs }
17221722
}
1723+
1724+
/// Triggers an SMI on the virtual CPU.
1725+
///
1726+
/// See documentation for `KVM_SMI`.
1727+
///
1728+
/// ```rust
1729+
/// # use kvm_ioctls::{Kvm, Cap};
1730+
/// let kvm = Kvm::new().unwrap();
1731+
/// let vm = kvm.create_vm().unwrap();
1732+
/// let vcpu = vm.create_vcpu(0).unwrap();
1733+
/// if kvm.check_extension(Cap::X86Smm) {
1734+
/// vcpu.smi().unwrap();
1735+
/// }
1736+
/// ```
1737+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
1738+
pub fn smi(&self) -> Result<()> {
1739+
// SAFETY: Safe because we call this with a Vcpu fd and we trust the kernel.
1740+
let ret = unsafe { ioctl(self, KVM_SMI()) };
1741+
match ret {
1742+
0 => Ok(()),
1743+
_ => Err(errno::Error::last()),
1744+
}
1745+
}
17231746
}
17241747

17251748
/// Helper function to create a new `VcpuFd`.

src/kvm_ioctls.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ ioctl_ior_nr!(KVM_ARM_PREFERRED_TARGET, KVMIO, 0xaf, kvm_vcpu_init);
240240
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
241241
ioctl_iowr_nr!(KVM_GET_REG_LIST, KVMIO, 0xb0, kvm_reg_list);
242242

243+
/* Available with KVM_CAP_X86_SMM */
244+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
245+
ioctl_io_nr!(KVM_SMI, KVMIO, 0xb7);
246+
243247
/* Available with KVM_CAP_ARM_SVE */
244248
#[cfg(target_arch = "aarch64")]
245249
ioctl_iow_nr!(KVM_ARM_VCPU_FINALIZE, KVMIO, 0xc2, std::os::raw::c_int);

0 commit comments

Comments
 (0)