diff --git a/pci/src/bus.rs b/pci/src/bus.rs index ec735cb1d..76f4ae128 100644 --- a/pci/src/bus.rs +++ b/pci/src/bus.rs @@ -9,6 +9,7 @@ use crate::device::{DeviceRelocation, Error as PciDeviceError, PciDevice}; use byteorder::{ByteOrder, LittleEndian}; use devices::BusDevice; use std; +use std::any::Any; use std::ops::DerefMut; use std::sync::{Arc, Mutex, Weak}; use vm_memory::{Address, GuestAddress, GuestUsize}; @@ -69,6 +70,10 @@ impl PciDevice for PciRoot { fn read_config_register(&self, reg_idx: usize) -> u32 { self.config.read_reg(reg_idx) } + + fn as_any(&mut self) -> &mut dyn Any { + self + } } pub struct PciBus { diff --git a/pci/src/device.rs b/pci/src/device.rs index 0aa693b54..9df2129d9 100755 --- a/pci/src/device.rs +++ b/pci/src/device.rs @@ -6,12 +6,12 @@ use crate::configuration::{self, PciBarRegionType}; use crate::msix::MsixTableEntry; use crate::PciInterruptPin; use devices::BusDevice; +use std::any::Any; use std::fmt::{self, Display}; use std::sync::Arc; use std::{self, io, result}; use vm_allocator::SystemAllocator; use vm_memory::{GuestAddress, GuestUsize}; -use vmm_sys_util::eventfd::EventFd; pub struct InterruptParameters<'a> { pub msix: Option<&'a MsixTableEntry>, @@ -78,11 +78,6 @@ pub trait PciDevice: BusDevice { Ok(Vec::new()) } - /// Gets a list of ioeventfds that should be registered with the running VM. The list is - /// returned as a Vec of (eventfd, addr, datamatch) tuples. - fn ioeventfds(&self) -> Vec<(&EventFd, u64, u64)> { - Vec::new() - } /// Sets a register in the configuration space. /// * `reg_idx` - The index of the config register to modify. /// * `offset` - Offset in to the register. @@ -110,6 +105,9 @@ pub trait PciDevice: BusDevice { fn move_bar(&mut self, _old_base: u64, _new_base: u64) -> result::Result<(), io::Error> { Ok(()) } + /// Provides a mutable reference to the Any trait. This is useful to let + /// the caller have access to the underlying type behind the trait. + fn as_any(&mut self) -> &mut dyn Any; } /// This trait defines a set of functions which can be triggered whenever a diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs index 5a4de68e6..1122a11fe 100644 --- a/vfio/src/vfio_pci.rs +++ b/vfio/src/vfio_pci.rs @@ -20,6 +20,7 @@ use pci::{ PciCapabilityID, PciClassCode, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciSubclass, MSIX_TABLE_ENTRY_SIZE, }; +use std::any::Any; use std::os::unix::io::AsRawFd; use std::ptr::null_mut; use std::sync::Arc; @@ -1045,4 +1046,8 @@ impl PciDevice for VfioPciDevice { Ok(()) } + + fn as_any(&mut self) -> &mut dyn Any { + self + } } diff --git a/vm-virtio/src/transport/pci_device.rs b/vm-virtio/src/transport/pci_device.rs index 16d31fd5d..1a0a66705 100755 --- a/vm-virtio/src/transport/pci_device.rs +++ b/vm-virtio/src/transport/pci_device.rs @@ -14,6 +14,7 @@ extern crate vm_memory; extern crate vmm_sys_util; use libc::EFD_NONBLOCK; +use std::any::Any; use std::sync::atomic::{AtomicU16, AtomicUsize, Ordering}; use std::sync::{Arc, Mutex, RwLock}; @@ -361,6 +362,22 @@ impl VirtioPciDevice { } } + pub fn ioeventfds(&self) -> Vec<(&EventFd, u64, u64)> { + let bar0 = self.configuration.get_bar_addr(self.settings_bar as usize); + let notify_base = bar0 + NOTIFICATION_BAR_OFFSET; + self.queue_evts() + .iter() + .enumerate() + .map(|(i, event)| { + ( + event, + notify_base + i as u64 * u64::from(NOTIFY_OFF_MULTIPLIER), + i as u64, + ) + }) + .collect() + } + fn add_pci_capabilities( &mut self, settings_bar: u8, @@ -528,22 +545,6 @@ impl PciDevice for VirtioPciDevice { self.configuration.detect_bar_reprogramming(reg_idx, data) } - fn ioeventfds(&self) -> Vec<(&EventFd, u64, u64)> { - let bar0 = self.configuration.get_bar_addr(self.settings_bar as usize); - let notify_base = bar0 + NOTIFICATION_BAR_OFFSET; - self.queue_evts() - .iter() - .enumerate() - .map(|(i, event)| { - ( - event, - notify_base + i as u64 * u64::from(NOTIFY_OFF_MULTIPLIER), - i as u64, - ) - }) - .collect() - } - fn allocate_bars( &mut self, allocator: &mut SystemAllocator, @@ -733,6 +734,10 @@ impl PciDevice for VirtioPciDevice { } } } + + fn as_any(&mut self) -> &mut dyn Any { + self + } } impl BusDevice for VirtioPciDevice { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 78c841fd7..9475d92b9 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -356,10 +356,13 @@ impl DeviceRelocation for AddressManager { } } - for (event, addr, _) in pci_dev.ioeventfds() { - let io_addr = IoEventAddress::Mmio(addr); - self.vm_fd - .register_ioevent(event.as_raw_fd(), &io_addr, NoDatamatch)?; + let any_dev = pci_dev.as_any(); + if let Some(virtio_pci_dev) = any_dev.downcast_ref::() { + for (event, addr, _) in virtio_pci_dev.ioeventfds() { + let io_addr = IoEventAddress::Mmio(addr); + self.vm_fd + .register_ioevent(event.as_raw_fd(), &io_addr, NoDatamatch)?; + } } pci_dev.move_bar(old_base, new_base)