From bb8cd9eb24c7e8ddd9a6b65ee13a0efe53bee873 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 20 Jan 2020 16:00:18 +0100 Subject: [PATCH] vmm: Use LegacyUserspaceInterruptGroup for acpi device This commit replaces the way legacy interrupts were handled with the brand new implementation of the legacy InterruptSourceGroup for KVM. Additionally, since it removes the last bit relying on the Interrupt trait, the trait and its implementation can be removed from the codebase. Signed-off-by: Sebastien Boeuf --- devices/src/acpi.rs | 9 +++++---- devices/src/lib.rs | 6 +----- vmm/src/device_manager.rs | 41 ++++++++++----------------------------- 3 files changed, 16 insertions(+), 40 deletions(-) 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