Skip to content

Commit 9b64903

Browse files
NunoDasNevesandreeaflorescu
authored andcommitted
ioctls: vm: Add register_irqfd_with_resample
Signed-off-by: Nuno Das Neves <[email protected]>
1 parent ccf0bda commit 9b64903

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

src/ioctls/vm.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,65 @@ impl VmFd {
896896
}
897897
}
898898

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+
899958
/// Unregisters an event that will, when signaled, trigger the `gsi` IRQ.
900959
///
901960
/// # Arguments
@@ -915,11 +974,15 @@ impl VmFd {
915974
/// let kvm = Kvm::new().unwrap();
916975
/// let vm = kvm.create_vm().unwrap();
917976
/// let evtfd = EventFd::new(EFD_NONBLOCK).unwrap();
977+
/// let resamplefd = EventFd::new(EFD_NONBLOCK).unwrap();
918978
/// #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
919979
/// {
920980
/// vm.create_irq_chip().unwrap();
921981
/// vm.register_irqfd(&evtfd, 0).unwrap();
922982
/// vm.unregister_irqfd(&evtfd, 0).unwrap();
983+
/// vm.register_irqfd_with_resample(&evtfd, &resamplefd, 0)
984+
/// .unwrap();
985+
/// vm.unregister_irqfd(&evtfd, 0).unwrap();
923986
/// }
924987
/// ```
925988
#[cfg(any(
@@ -1792,6 +1855,8 @@ mod tests {
17921855
let evtfd1 = EventFd::new(EFD_NONBLOCK).unwrap();
17931856
let evtfd2 = EventFd::new(EFD_NONBLOCK).unwrap();
17941857
let evtfd3 = EventFd::new(EFD_NONBLOCK).unwrap();
1858+
let evtfd4 = EventFd::new(EFD_NONBLOCK).unwrap();
1859+
let resamplefd = EventFd::new(EFD_NONBLOCK).unwrap();
17951860

17961861
assert!(vm_fd.create_irq_chip().is_ok());
17971862

@@ -1808,6 +1873,17 @@ mod tests {
18081873
assert!(vm_fd.register_irqfd(&evtfd3, 5).is_err());
18091874
// KVM irqfd doesn't report failure on this case:(
18101875
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+
}
18111887
}
18121888

18131889
#[test]
@@ -1818,6 +1894,8 @@ mod tests {
18181894
let evtfd1 = EventFd::new(EFD_NONBLOCK).unwrap();
18191895
let evtfd2 = EventFd::new(EFD_NONBLOCK).unwrap();
18201896
let evtfd3 = EventFd::new(EFD_NONBLOCK).unwrap();
1897+
let evtfd4 = EventFd::new(EFD_NONBLOCK).unwrap();
1898+
let resamplefd = EventFd::new(EFD_NONBLOCK).unwrap();
18211899

18221900
// Create the vGIC device.
18231901
let vgic_fd = create_gic_device(&vm_fd, 0);
@@ -1845,6 +1923,17 @@ mod tests {
18451923
assert!(vm_fd.register_irqfd(&evtfd3, 5).is_err());
18461924
// KVM irqfd doesn't report failure on this case:(
18471925
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+
}
18481937
}
18491938

18501939
#[test]

0 commit comments

Comments
 (0)