Skip to content

Commit c576bcc

Browse files
committed
Add support for KVM_REINJECT_CONTROL ioctl on x86_64
This commit introduces support for the `KVM_REINJECT_CONTROL` VM ioctl on x86_64, along with a convenience method `disable_pit_reinjection` on 'VmFd` for easier management of PIT reinjection settings. Signed-off-by: Karuboniru <yanqiyu01@gmail.com>
1 parent 3ffc9b6 commit c576bcc

3 files changed

Lines changed: 80 additions & 0 deletions

File tree

kvm-ioctls/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Plumb through KVM_CAP_DIRTY_LOG_RING as DirtyLogRing cap.
66
- [[#359]](https://github.com/rust-vmm/kvm/pull/359) Add support for `KVM_SET_MSR_FILTER` vm ioctl on x86_64.
7+
- Add support for `KVM_REINJECT_CONTROL` vm ioctl on x86_64, also a shortcut `disable_pit_reinjection` on `VmFd`.
78

89
## v0.24.0
910

kvm-ioctls/src/ioctls/vm.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,68 @@ impl VmFd {
410410
}
411411
}
412412

413+
/// Controls the PIT Reinjection feature.
414+
///
415+
/// # Arguments
416+
///
417+
/// * rejection_control - `kvm_pit_rejection_control` structure to enable/disable PIT reinjection.
418+
///
419+
/// # Example
420+
/// ```rust
421+
/// extern crate kvm_ioctls;
422+
/// extern crate kvm_bindings;
423+
/// use kvm_ioctls::Kvm;
424+
/// use kvm_bindings::{kvm_reinject_control};
425+
/// let kvm = Kvm::new().unwrap();
426+
/// let vm = kvm.create_vm().unwrap();
427+
/// vm.create_irq_chip().unwrap();
428+
/// let pit_config = kvm_pit_config::default();
429+
/// vm.create_pit2(pit_config).unwrap();
430+
///
431+
/// let rejection_control = kvm_reinject_control {
432+
/// pit_reinject: 0,
433+
/// ..Default::default()
434+
/// };
435+
/// vm.control_pit_reinjection(rejection_control).unwrap();
436+
#[cfg(target_arch = "x86_64")]
437+
pub fn control_pit_reinjection(&self, rejection_control: kvm_reinject_control) -> Result<()> {
438+
// SAFETY: Safe because we know that our file is a VM fd and we verify the return result.
439+
let ret = unsafe { ioctl_with_ref(self, KVM_REINJECT_CONTROL(), &rejection_control) };
440+
if ret == 0 {
441+
Ok(())
442+
} else {
443+
Err(errno::Error::last())
444+
}
445+
}
446+
447+
/// Disable PIT reinjection.
448+
///
449+
/// # equivalent to calling `control_pit_reinjection` with `pit_reinject` set to 0.
450+
///
451+
/// # kernel doc recommend that this is always done unless the guest OS requires PIT
452+
/// # to do reinjection.
453+
///
454+
/// # Example
455+
/// ```rust
456+
/// extern crate kvm_ioctls;
457+
/// extern crate kvm_bindings;
458+
/// use kvm_ioctls::Kvm;
459+
/// let kvm = Kvm::new().unwrap();
460+
/// let vm = kvm.create_vm().unwrap();
461+
/// vm.create_irq_chip().unwrap();
462+
/// let pit_config = kvm_bindings::kvm_pit_config::default();
463+
/// vm.create_pit2(pit_config).unwrap();
464+
/// vm.disable_pit_reinjection().unwrap();
465+
/// ```
466+
#[cfg(target_arch = "x86_64")]
467+
pub fn disable_pit_reinjection(&self) -> Result<()> {
468+
let rejection_control = kvm_reinject_control {
469+
pit_reinject: 0,
470+
..Default::default()
471+
};
472+
self.control_pit_reinjection(rejection_control)
473+
}
474+
413475
/// Creates a PIT as per the `KVM_CREATE_PIT2` ioctl.
414476
///
415477
/// # Arguments
@@ -2407,6 +2469,20 @@ mod tests {
24072469
assert_eq!(pit2, other_pit2);
24082470
}
24092471

2472+
#[test]
2473+
#[cfg(target_arch = "x86_64")]
2474+
fn test_disable_reinjection() {
2475+
let kvm = Kvm::new().unwrap();
2476+
let vm = kvm.create_vm().unwrap();
2477+
vm.create_irq_chip().unwrap();
2478+
vm.create_pit2(kvm_pit_config::default()).unwrap();
2479+
let reinjection = kvm_reinject_control {
2480+
pit_reinject: 0,
2481+
..Default::default()
2482+
};
2483+
vm.control_pit_reinjection(reinjection).unwrap();
2484+
}
2485+
24102486
#[cfg(target_arch = "x86_64")]
24112487
#[test]
24122488
fn test_clock() {

kvm-ioctls/src/kvm_ioctls.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ ioctl_iow_nr!(
8383
target_arch = "riscv64"
8484
))]
8585
ioctl_iow_nr!(KVM_SET_GSI_ROUTING, KVMIO, 0x6a, kvm_irq_routing);
86+
/* Available with KVM_CAP_REINJECT_CONTROL */
87+
#[cfg(target_arch = "x86_64")]
88+
ioctl_io_nr!(KVM_REINJECT_CONTROL, KVMIO, 0x71);
8689
/* Available with KVM_CAP_IRQFD */
8790
#[cfg(any(
8891
target_arch = "x86_64",

0 commit comments

Comments
 (0)