From aa12c74bff702e25dffb0c2de0240754c9c51c90 Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Mon, 9 Jul 2018 13:35:40 -0700 Subject: [PATCH] devices: pci: add ioeventfds to PciDevice trait VirtioDevices and potentially others need to register ioeventfds that will be triggered when guests write to certain addresses. Allow PciDevices to return an array of ioeventfds that the VM can install. Change-Id: I2524c4e8c04f75a8d7868cac998304aecbb29c40 Signed-off-by: Dylan Reid Reviewed-on: https://chromium-review.googlesource.com/1237360 Commit-Ready: Daniel Verkamp Tested-by: Daniel Verkamp --- aarch64/src/lib.rs | 3 ++- arch/src/lib.rs | 15 ++++++++++++--- devices/src/pci/pci_device.rs | 10 ++++++++++ x86_64/src/lib.rs | 3 ++- 4 files changed, 26 insertions(+), 5 deletions(-) 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));