diff --git a/vm-virtio/src/transport/mmio.rs b/vm-virtio/src/transport/mmio.rs index a9a21a77f..993afe2cb 100644 --- a/vm-virtio/src/transport/mmio.rs +++ b/vm-virtio/src/transport/mmio.rs @@ -10,11 +10,12 @@ use crate::{ }; use arc_swap::ArcSwap; use byteorder::{ByteOrder, LittleEndian}; -use devices::{BusDevice, Interrupt}; +use devices::BusDevice; use libc::EFD_NONBLOCK; use std::result; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; +use vm_device::interrupt::InterruptSourceGroup; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{GuestAddress, GuestMemoryMmap}; use vmm_sys_util::{errno::Result, eventfd::EventFd}; @@ -26,11 +27,14 @@ const MMIO_VERSION: u32 = 2; pub struct VirtioInterruptIntx { interrupt_status: Arc, - interrupt: Box, + interrupt: Arc>, } impl VirtioInterruptIntx { - pub fn new(interrupt_status: Arc, interrupt: Box) -> Self { + pub fn new( + interrupt_status: Arc, + interrupt: Arc>, + ) -> Self { VirtioInterruptIntx { interrupt_status, interrupt, @@ -51,7 +55,7 @@ impl VirtioInterrupt for VirtioInterruptIntx { self.interrupt_status .fetch_or(status as usize, Ordering::SeqCst); - self.interrupt.deliver() + self.interrupt.trigger(0) } } @@ -157,7 +161,7 @@ impl MmioDevice { } } - pub fn assign_interrupt(&mut self, interrupt: Box) { + pub fn assign_interrupt(&mut self, interrupt: Arc>) { self.interrupt_cb = Some(Arc::new(VirtioInterruptIntx::new( self.interrupt_status.clone(), interrupt, diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index b7c00e452..a28e8fceb 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -12,7 +12,6 @@ extern crate vm_device; use crate::config::{ConsoleOutputMode, VmConfig}; -#[cfg(feature = "pci_support")] use crate::interrupt::{KvmInterruptManager, KvmRoutingEntry}; use crate::memory_manager::{Error as MemoryManagerError, MemoryManager}; use crate::vm::VmInfo; @@ -30,7 +29,6 @@ use pci::{ DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot, }; use qcow::{self, ImageType, QcowFile}; -#[cfg(feature = "pci_support")] use std::collections::HashMap; use std::fs::{File, OpenOptions}; use std::io::{self, sink, stdout}; @@ -44,8 +42,9 @@ use std::sync::{Arc, Mutex}; #[cfg(feature = "pci_support")] use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError}; use vm_allocator::SystemAllocator; -#[cfg(feature = "pci_support")] use vm_device::interrupt::InterruptManager; +#[cfg(feature = "mmio_support")] +use vm_device::interrupt::{InterruptIndex, PIN_IRQ}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::GuestAddress; use vm_memory::{Address, GuestMemoryMmap, GuestUsize}; @@ -182,15 +181,17 @@ pub enum DeviceManagerError { // Error from a memory manager operation MemoryManager(MemoryManagerError), + + /// Failed to create new interrupt source group. + CreateInterruptGroup(io::Error), + + /// Failed to update interrupt source group. + UpdateInterruptGroup(io::Error), } pub type DeviceManagerResult = result::Result; type VirtioDeviceArc = Arc>; -struct InterruptInfo<'a> { - _ioapic: &'a Arc>, -} - struct UserIoapicIrq { ioapic: Arc>, irq: usize, @@ -445,7 +446,6 @@ impl DeviceManager { }); let ioapic = DeviceManager::add_ioapic(vm_info, &address_manager)?; - let interrupt_info = InterruptInfo { _ioapic: &ioapic }; // Create a shared list of GSI that can be shared through all PCI // devices. This way, we can maintain the full list of used GSI, @@ -507,7 +507,7 @@ impl DeviceManager { vm_info, &address_manager, virtio_devices, - &interrupt_info, + &interrupt_manager, &mut cmdline_additions, &mut migratable_devices, )?; @@ -654,7 +654,7 @@ impl DeviceManager { vm_info: &VmInfo, address_manager: &Arc, virtio_devices: Vec<(Arc>, bool)>, - interrupt_info: &InterruptInfo, + interrupt_manager: &Arc, mut cmdline_additions: &mut Vec, migratable_devices: &mut Vec>>, ) -> DeviceManagerResult<()> { @@ -672,7 +672,7 @@ impl DeviceManager { vm_info.memory, &address_manager, vm_info.vm_fd, - &interrupt_info, + interrupt_manager, addr, &mut cmdline_additions, migratable_devices, @@ -1526,7 +1526,7 @@ impl DeviceManager { memory: &Arc>, address_manager: &Arc, vm_fd: &Arc, - interrupt_info: &InterruptInfo, + interrupt_manager: &Arc, mmio_base: GuestAddress, cmdline_additions: &mut Vec, migratable_devices: &mut Vec>>, @@ -1548,12 +1548,11 @@ impl DeviceManager { .allocate_irq() .ok_or(DeviceManagerError::AllocateIrq)?; - let interrupt: Box = Box::new(UserIoapicIrq::new( - interrupt_info._ioapic.clone(), - irq_num as usize, - )); + let interrupt_group = interrupt_manager + .create_group(PIN_IRQ, irq_num as InterruptIndex, 1 as InterruptIndex) + .map_err(DeviceManagerError::CreateInterruptGroup)?; - mmio_device.assign_interrupt(interrupt); + mmio_device.assign_interrupt(interrupt_group); let mmio_device_arc = Arc::new(Mutex::new(mmio_device)); address_manager