@@ -896,6 +896,65 @@ impl VmFd {
896
896
}
897
897
}
898
898
899
+ /// Registers an event that will, when signaled, assert the `gsi` IRQ.
900
+ /// If the irqchip is resampled by the guest, the IRQ is de-asserted,
901
+ /// and `resamplefd` is notified.
902
+ ///
903
+ /// # Arguments
904
+ ///
905
+ /// * `fd` - `EventFd` to be signaled.
906
+ /// * `resamplefd` - `EventFd`to be notified on resample.
907
+ /// * `gsi` - IRQ to be triggered.
908
+ ///
909
+ /// # Example
910
+ ///
911
+ /// ```rust
912
+ /// # extern crate kvm_ioctls;
913
+ /// # extern crate libc;
914
+ /// # extern crate vmm_sys_util;
915
+ /// # use kvm_ioctls::Kvm;
916
+ /// # use libc::EFD_NONBLOCK;
917
+ /// # use vmm_sys_util::eventfd::EventFd;
918
+ /// let kvm = Kvm::new().unwrap();
919
+ /// let vm = kvm.create_vm().unwrap();
920
+ /// let evtfd = EventFd::new(EFD_NONBLOCK).unwrap();
921
+ /// let resamplefd = EventFd::new(EFD_NONBLOCK).unwrap();
922
+ /// #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
923
+ /// {
924
+ /// vm.create_irq_chip().unwrap();
925
+ /// vm.register_irqfd_with_resample(&evtfd, &resamplefd, 0)
926
+ /// .unwrap();
927
+ /// }
928
+ /// ```
929
+ #[ cfg( any(
930
+ target_arch = "x86" ,
931
+ target_arch = "x86_64" ,
932
+ target_arch = "arm" ,
933
+ target_arch = "aarch64"
934
+ ) ) ]
935
+ pub fn register_irqfd_with_resample (
936
+ & self ,
937
+ fd : & EventFd ,
938
+ resamplefd : & EventFd ,
939
+ gsi : u32 ,
940
+ ) -> Result < ( ) > {
941
+ let irqfd = kvm_irqfd {
942
+ fd : fd. as_raw_fd ( ) as u32 ,
943
+ resamplefd : resamplefd. as_raw_fd ( ) as u32 ,
944
+ gsi,
945
+ flags : KVM_IRQFD_FLAG_RESAMPLE ,
946
+ ..Default :: default ( )
947
+ } ;
948
+ // Safe because we know that our file is a VM fd, we know the kernel will only read the
949
+ // correct amount of memory from our pointer, and we verify the return result.
950
+ let ret = unsafe { ioctl_with_ref ( self , KVM_IRQFD ( ) , & irqfd) } ;
951
+ if ret == 0 {
952
+ Ok ( ( ) )
953
+ } else {
954
+ Err ( errno:: Error :: last ( ) )
955
+ }
956
+ }
957
+
899
958
/// Unregisters an event that will, when signaled, trigger the `gsi` IRQ.
900
959
///
901
960
/// # Arguments
@@ -915,11 +974,15 @@ impl VmFd {
915
974
/// let kvm = Kvm::new().unwrap();
916
975
/// let vm = kvm.create_vm().unwrap();
917
976
/// let evtfd = EventFd::new(EFD_NONBLOCK).unwrap();
977
+ /// let resamplefd = EventFd::new(EFD_NONBLOCK).unwrap();
918
978
/// #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
919
979
/// {
920
980
/// vm.create_irq_chip().unwrap();
921
981
/// vm.register_irqfd(&evtfd, 0).unwrap();
922
982
/// vm.unregister_irqfd(&evtfd, 0).unwrap();
983
+ /// vm.register_irqfd_with_resample(&evtfd, &resamplefd, 0)
984
+ /// .unwrap();
985
+ /// vm.unregister_irqfd(&evtfd, 0).unwrap();
923
986
/// }
924
987
/// ```
925
988
#[ cfg( any(
@@ -1792,6 +1855,8 @@ mod tests {
1792
1855
let evtfd1 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1793
1856
let evtfd2 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1794
1857
let evtfd3 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1858
+ let evtfd4 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1859
+ let resamplefd = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1795
1860
1796
1861
assert ! ( vm_fd. create_irq_chip( ) . is_ok( ) ) ;
1797
1862
@@ -1808,6 +1873,17 @@ mod tests {
1808
1873
assert ! ( vm_fd. register_irqfd( & evtfd3, 5 ) . is_err( ) ) ;
1809
1874
// KVM irqfd doesn't report failure on this case:(
1810
1875
assert ! ( vm_fd. unregister_irqfd( & evtfd3, 5 ) . is_ok( ) ) ;
1876
+
1877
+ if vm_fd. check_extension ( Cap :: IrqfdResample ) {
1878
+ assert ! ( vm_fd
1879
+ . register_irqfd_with_resample( & evtfd4, & resamplefd, 6 )
1880
+ . is_ok( ) ) ;
1881
+ assert ! ( vm_fd. unregister_irqfd( & evtfd4, 6 ) . is_ok( ) ) ;
1882
+ } else {
1883
+ assert ! ( vm_fd
1884
+ . register_irqfd_with_resample( & evtfd4, & resamplefd, 6 )
1885
+ . is_err( ) ) ;
1886
+ }
1811
1887
}
1812
1888
1813
1889
#[ test]
@@ -1818,6 +1894,8 @@ mod tests {
1818
1894
let evtfd1 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1819
1895
let evtfd2 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1820
1896
let evtfd3 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1897
+ let evtfd4 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1898
+ let resamplefd = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1821
1899
1822
1900
// Create the vGIC device.
1823
1901
let vgic_fd = create_gic_device ( & vm_fd, 0 ) ;
@@ -1845,6 +1923,17 @@ mod tests {
1845
1923
assert ! ( vm_fd. register_irqfd( & evtfd3, 5 ) . is_err( ) ) ;
1846
1924
// KVM irqfd doesn't report failure on this case:(
1847
1925
assert ! ( vm_fd. unregister_irqfd( & evtfd3, 5 ) . is_ok( ) ) ;
1926
+
1927
+ if vm_fd. check_extension ( Cap :: IrqfdResample ) {
1928
+ assert ! ( vm_fd
1929
+ . register_irqfd_with_resample( & evtfd4, & resamplefd, 6 )
1930
+ . is_ok( ) ) ;
1931
+ assert ! ( vm_fd. unregister_irqfd( & evtfd4, 6 ) . is_ok( ) ) ;
1932
+ } else {
1933
+ assert ! ( vm_fd
1934
+ . register_irqfd_with_resample( & evtfd4, & resamplefd, 6 )
1935
+ . is_err( ) ) ;
1936
+ }
1848
1937
}
1849
1938
1850
1939
#[ test]
0 commit comments