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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-01-20 16:00:18 +01:00 committed by Samuel Ortiz
parent 75e22ff34e
commit bb8cd9eb24
3 changed files with 16 additions and 40 deletions

View File

@ -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<dyn Interrupt>,
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
notification_type: HotPlugNotificationFlags,
ged_irq: u32,
}
impl AcpiGEDDevice {
pub fn new(interrupt: Box<dyn Interrupt>, ged_irq: u32) -> AcpiGEDDevice {
pub fn new(interrupt: Arc<Box<dyn InterruptSourceGroup>>, 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 {

View File

@ -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;

View File

@ -191,32 +191,6 @@ pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
type VirtioDeviceArc = Arc<Mutex<dyn vm_virtio::VirtioDevice>>;
struct UserIoapicIrq {
ioapic: Arc<Mutex<ioapic::Ioapic>>,
irq: usize,
}
impl UserIoapicIrq {
fn new(ioapic: Arc<Mutex<ioapic::Ioapic>>, 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<AddressManager>,
interrupt_manager: &Arc<dyn InterruptManager>,
reset_evt: EventFd,
exit_evt: EventFd,
ioapic: &Arc<Mutex<ioapic::Ioapic>>,
) -> DeviceManagerResult<Option<Arc<Mutex<devices::AcpiGEDDevice>>>> {
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<dyn devices::Interrupt> =
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