diff --git a/devices/src/acpi.rs b/devices/src/acpi.rs index 4ab70cf71..c342817b4 100644 --- a/devices/src/acpi.rs +++ b/devices/src/acpi.rs @@ -3,10 +3,11 @@ // SPDX-License-Identifier: Apache-2.0 // +use std::sync::Arc; +use vm_device::interrupt::InterruptSourceGroup; use vmm_sys_util::eventfd::EventFd; use BusDevice; use HotPlugNotificationFlags; -use Interrupt; /// A device for handling ACPI shutdown and reboot pub struct AcpiShutdownDevice { @@ -56,13 +57,13 @@ impl BusDevice for AcpiShutdownDevice { /// A device for handling ACPI GED event generation pub struct AcpiGEDDevice { - interrupt: Box, + interrupt: Arc>, notification_type: HotPlugNotificationFlags, ged_irq: u32, } impl AcpiGEDDevice { - pub fn new(interrupt: Box, ged_irq: u32) -> AcpiGEDDevice { + pub fn new(interrupt: Arc>, ged_irq: u32) -> AcpiGEDDevice { AcpiGEDDevice { interrupt, notification_type: HotPlugNotificationFlags::NO_DEVICES_CHANGED, @@ -75,7 +76,7 @@ impl AcpiGEDDevice { notification_type: HotPlugNotificationFlags, ) -> Result<(), std::io::Error> { self.notification_type |= notification_type; - self.interrupt.deliver() + self.interrupt.trigger(0) } pub fn irq(&self) -> u32 { diff --git a/devices/src/lib.rs b/devices/src/lib.rs index c99a4d204..41b9800bd 100644 --- a/devices/src/lib.rs +++ b/devices/src/lib.rs @@ -20,7 +20,7 @@ extern crate vm_memory; extern crate vmm_sys_util; use std::fs::File; -use std::{io, result}; +use std::io; #[cfg(feature = "acpi")] mod acpi; @@ -70,10 +70,6 @@ pub enum Error { IoError(io::Error), } -pub trait Interrupt: Send + Sync { - fn deliver(&self) -> result::Result<(), std::io::Error>; -} - bitflags! { pub struct HotPlugNotificationFlags: u8 { const NO_DEVICES_CHANGED = 0; diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index fdc1b0ad1..cb53219c6 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -191,32 +191,6 @@ pub type DeviceManagerResult = result::Result; type VirtioDeviceArc = Arc>; -struct UserIoapicIrq { - ioapic: Arc>, - irq: usize, -} - -impl UserIoapicIrq { - fn new(ioapic: Arc>, irq: usize) -> Self { - UserIoapicIrq { ioapic, irq } - } -} - -impl devices::Interrupt for UserIoapicIrq { - fn deliver(&self) -> result::Result<(), io::Error> { - self.ioapic - .lock() - .unwrap() - .service_irq(self.irq) - .map_err(|e| { - std::io::Error::new( - std::io::ErrorKind::Other, - format!("failed to inject IRQ #{}: {:?}", self.irq, e), - ) - }) - } -} - pub fn get_win_size() -> (u16, u16) { #[repr(C)] struct WS { @@ -486,9 +460,9 @@ impl DeviceManager { let ged_notification_device = DeviceManager::add_acpi_devices( vm_info, &address_manager, + &interrupt_manager, reset_evt.try_clone().map_err(DeviceManagerError::EventFd)?, _exit_evt.try_clone().map_err(DeviceManagerError::EventFd)?, - &ioapic, )?; if cfg!(feature = "pci_support") { @@ -708,9 +682,9 @@ impl DeviceManager { fn add_acpi_devices( vm_info: &VmInfo, address_manager: &Arc, + interrupt_manager: &Arc, reset_evt: EventFd, exit_evt: EventFd, - ioapic: &Arc>, ) -> DeviceManagerResult>>> { let acpi_device = Arc::new(Mutex::new(devices::AcpiShutdownDevice::new( exit_evt, reset_evt, @@ -734,10 +708,15 @@ impl DeviceManager { .unwrap() .allocate_irq() .unwrap(); - let interrupt: Box = - Box::new(UserIoapicIrq::new(ioapic.clone(), ged_irq as usize)); - let ged_device = Arc::new(Mutex::new(devices::AcpiGEDDevice::new(interrupt, ged_irq))); + let interrupt_group = interrupt_manager + .create_group(PIN_IRQ, ged_irq as InterruptIndex, 1 as InterruptIndex) + .map_err(DeviceManagerError::CreateInterruptGroup)?; + + let ged_device = Arc::new(Mutex::new(devices::AcpiGEDDevice::new( + interrupt_group, + ged_irq, + ))); address_manager .allocator