diff --git a/aarch64/src/lib.rs b/aarch64/src/lib.rs index e78ee55c8a..88522b1852 100644 --- a/aarch64/src/lib.rs +++ b/aarch64/src/lib.rs @@ -209,7 +209,8 @@ impl arch::LinuxArch for AArch64 { let (pci, pci_irqs) = arch::generate_pci_root(components.pci_devices, &mut mmio_bus, - &mut resources) + &mut resources, + &mut vm) .map_err(Error::CreatePciRoot)?; let exit_evt = EventFd::new().map_err(Error::CreateEventFd)?; diff --git a/arch/src/lib.rs b/arch/src/lib.rs index 807a4dfa3d..afea720134 100644 --- a/arch/src/lib.rs +++ b/arch/src/lib.rs @@ -20,7 +20,7 @@ use devices::{Bus, BusError, PciDevice, PciDeviceError, PciInterruptPin, PciRoot, ProxyDevice, Serial}; use devices::virtio::VirtioDevice; use io_jail::Minijail; -use kvm::{IoeventAddress, Kvm, Vm, Vcpu}; +use kvm::{IoeventAddress, Kvm, NoDatamatch, Vm, Vcpu}; use sys_util::{EventFd, GuestMemory, syslog}; use resources::SystemAllocator; @@ -136,7 +136,8 @@ impl fmt::Display for DeviceRegistrationError { /// Creates a root PCI device for use by this Vm. pub fn generate_pci_root(devices: Vec<(Box, Minijail)>, mmio_bus: &mut Bus, - resources: &mut SystemAllocator) + resources: &mut SystemAllocator, + vm: &mut Vm) -> std::result::Result<(PciRoot, Vec<(u32, PciInterruptPin)>), DeviceRegistrationError> { let mut root = PciRoot::new(); @@ -146,7 +147,9 @@ pub fn generate_pci_root(devices: Vec<(Box, Minijail)>, syslog::push_fds(&mut keep_fds); let irqfd = EventFd::new().map_err(DeviceRegistrationError::EventFdCreate)?; - let irq_num = resources.allocate_irq().ok_or(DeviceRegistrationError::AllocateIrq)? as u32; + let irq_num = resources + .allocate_irq() + .ok_or(DeviceRegistrationError::AllocateIrq)? as u32; let pci_irq_pin = match dev_idx % 4 { 0 => PciInterruptPin::IntA, 1 => PciInterruptPin::IntB, @@ -160,6 +163,12 @@ pub fn generate_pci_root(devices: Vec<(Box, Minijail)>, let ranges = device .allocate_io_bars(resources) .map_err(DeviceRegistrationError::AllocateIoAddrs)?; + for (event, addr) in device.ioeventfds() { + let io_addr = IoeventAddress::Mmio(addr); + vm.register_ioevent(&event, io_addr, NoDatamatch) + .map_err(DeviceRegistrationError::RegisterIoevent)?; + keep_fds.push(event.as_raw_fd()); + } let proxy = ProxyDevice::new(device, &jail, keep_fds) .map_err(DeviceRegistrationError::ProxyDeviceCreation)?; let arced_dev = Arc::new(Mutex::new(proxy)); diff --git a/devices/src/pci/pci_device.rs b/devices/src/pci/pci_device.rs index 3e02db34a4..80d99e37dd 100644 --- a/devices/src/pci/pci_device.rs +++ b/devices/src/pci/pci_device.rs @@ -37,6 +37,11 @@ pub trait PciDevice: Send { ) -> Result> { 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) tuples. + fn ioeventfds(&self) -> Vec<(&EventFd, u64)> { + Vec::new() + } /// Gets the configuration registers of the Pci Device. fn config_registers(&self) -> &PciConfiguration; // TODO - remove these /// Gets the configuration registers of the Pci Device for modification. @@ -98,6 +103,11 @@ impl PciDevice for Box { ) -> Result> { (**self).allocate_io_bars(resources) } + /// Gets a list of ioeventfds that should be registered with the running VM. The list is + /// returned as a Vec of (eventfd, addr) tuples. + fn ioeventfds(&self) -> Vec<(&EventFd, u64)> { + (**self).ioeventfds() + } /// Gets the configuration registers of the Pci Device. fn config_registers(&self) -> &PciConfiguration { (**self).config_registers() diff --git a/x86_64/src/lib.rs b/x86_64/src/lib.rs index bee8bff623..0d494c0282 100644 --- a/x86_64/src/lib.rs +++ b/x86_64/src/lib.rs @@ -277,7 +277,8 @@ impl arch::LinuxArch for X8664arch { let (pci, pci_irqs) = arch::generate_pci_root(components.pci_devices, &mut mmio_bus, - &mut resources) + &mut resources, + &mut vm) .map_err(Error::CreatePciRoot)?; let pci_bus = Arc::new(Mutex::new(pci));