From ef7aba82cc13382909cf8d704d88cbc87caf61d2 Mon Sep 17 00:00:00 2001 From: "Jason Cai (Xiang Feng)" Date: Wed, 11 Mar 2020 16:55:56 +0800 Subject: [PATCH] Support `datamatch` when unregister ioevent Whe unregistering an ioevent, the `datamatch` field should be set correctly, otherwise it may unregister undesired ioevent. Signed-off-by: Jason Cai (Xiang Feng) Signed-off-by: Liu Jiang --- coverage_config_x86_64.json | 2 +- src/ioctls/vm.rs | 36 +++++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/coverage_config_x86_64.json b/coverage_config_x86_64.json index eba81b31..d0bb9002 100644 --- a/coverage_config_x86_64.json +++ b/coverage_config_x86_64.json @@ -1,5 +1,5 @@ { - "coverage_score": 91.3, + "coverage_score": 91.4, "exclude_path": "", "crate_features": "" } diff --git a/src/ioctls/vm.rs b/src/ioctls/vm.rs index 702d997b..599516b8 100644 --- a/src/ioctls/vm.rs +++ b/src/ioctls/vm.rs @@ -636,23 +636,33 @@ impl VmFd { /// .register_ioevent(&evtfd, &pio_addr, NoDatamatch) /// .unwrap(); /// vm_fd - /// .register_ioevent(&evtfd, &mmio_addr, NoDatamatch) + /// .register_ioevent(&evtfd, &mmio_addr, 0x1234u32) /// .unwrap(); /// vm_fd - /// .unregister_ioevent(&evtfd, &pio_addr) + /// .unregister_ioevent(&evtfd, &pio_addr, NoDatamatch) /// .unwrap(); /// vm_fd - /// .unregister_ioevent(&evtfd, &mmio_addr) + /// .unregister_ioevent(&evtfd, &mmio_addr, 0x1234u32) /// .unwrap(); /// ``` /// - pub fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> Result<()> { + pub fn unregister_ioevent>( + &self, + fd: &EventFd, + addr: &IoEventAddress, + datamatch: T, + ) -> Result<()> { let mut flags = 1 << kvm_ioeventfd_flag_nr_deassign; + if std::mem::size_of::() > 0 { + flags |= 1 << kvm_ioeventfd_flag_nr_datamatch + } if let IoEventAddress::Pio(_) = *addr { flags |= 1 << kvm_ioeventfd_flag_nr_pio } let ioeventfd = kvm_ioeventfd { + datamatch: datamatch.into(), + len: std::mem::size_of::() as u32, addr: match addr { IoEventAddress::Pio(ref p) => *p as u64, IoEventAddress::Mmio(ref m) => *m, @@ -1440,21 +1450,29 @@ mod tests { let mmio_addr = IoEventAddress::Mmio(0x1000); // First try to unregister addresses which have not been registered. - assert!(vm_fd.unregister_ioevent(&evtfd, &pio_addr).is_err()); - assert!(vm_fd.unregister_ioevent(&evtfd, &mmio_addr).is_err()); + assert!(vm_fd + .unregister_ioevent(&evtfd, &pio_addr, NoDatamatch) + .is_err()); + assert!(vm_fd + .unregister_ioevent(&evtfd, &mmio_addr, NoDatamatch) + .is_err()); // Now register the addresses assert!(vm_fd .register_ioevent(&evtfd, &pio_addr, NoDatamatch) .is_ok()); assert!(vm_fd - .register_ioevent(&evtfd, &mmio_addr, NoDatamatch) + .register_ioevent(&evtfd, &mmio_addr, 0x1337u16) .is_ok()); // Try again unregistering the addresses. This time it should work // since they have been previously registered. - assert!(vm_fd.unregister_ioevent(&evtfd, &pio_addr).is_ok()); - assert!(vm_fd.unregister_ioevent(&evtfd, &mmio_addr).is_ok()); + assert!(vm_fd + .unregister_ioevent(&evtfd, &pio_addr, NoDatamatch) + .is_ok()); + assert!(vm_fd + .unregister_ioevent(&evtfd, &mmio_addr, 0x1337u16) + .is_ok()); } #[test]