@@ -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 ( ) {
0 commit comments