mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-05 13:05:45 +00:00
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:
parent
75e22ff34e
commit
bb8cd9eb24
@ -3,10 +3,11 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
use vm_device::interrupt::InterruptSourceGroup;
|
||||||
use vmm_sys_util::eventfd::EventFd;
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
use BusDevice;
|
use BusDevice;
|
||||||
use HotPlugNotificationFlags;
|
use HotPlugNotificationFlags;
|
||||||
use Interrupt;
|
|
||||||
|
|
||||||
/// A device for handling ACPI shutdown and reboot
|
/// A device for handling ACPI shutdown and reboot
|
||||||
pub struct AcpiShutdownDevice {
|
pub struct AcpiShutdownDevice {
|
||||||
@ -56,13 +57,13 @@ impl BusDevice for AcpiShutdownDevice {
|
|||||||
|
|
||||||
/// A device for handling ACPI GED event generation
|
/// A device for handling ACPI GED event generation
|
||||||
pub struct AcpiGEDDevice {
|
pub struct AcpiGEDDevice {
|
||||||
interrupt: Box<dyn Interrupt>,
|
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
|
||||||
notification_type: HotPlugNotificationFlags,
|
notification_type: HotPlugNotificationFlags,
|
||||||
ged_irq: u32,
|
ged_irq: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AcpiGEDDevice {
|
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 {
|
AcpiGEDDevice {
|
||||||
interrupt,
|
interrupt,
|
||||||
notification_type: HotPlugNotificationFlags::NO_DEVICES_CHANGED,
|
notification_type: HotPlugNotificationFlags::NO_DEVICES_CHANGED,
|
||||||
@ -75,7 +76,7 @@ impl AcpiGEDDevice {
|
|||||||
notification_type: HotPlugNotificationFlags,
|
notification_type: HotPlugNotificationFlags,
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
self.notification_type |= notification_type;
|
self.notification_type |= notification_type;
|
||||||
self.interrupt.deliver()
|
self.interrupt.trigger(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn irq(&self) -> u32 {
|
pub fn irq(&self) -> u32 {
|
||||||
|
@ -20,7 +20,7 @@ extern crate vm_memory;
|
|||||||
extern crate vmm_sys_util;
|
extern crate vmm_sys_util;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::{io, result};
|
use std::io;
|
||||||
|
|
||||||
#[cfg(feature = "acpi")]
|
#[cfg(feature = "acpi")]
|
||||||
mod acpi;
|
mod acpi;
|
||||||
@ -70,10 +70,6 @@ pub enum Error {
|
|||||||
IoError(io::Error),
|
IoError(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Interrupt: Send + Sync {
|
|
||||||
fn deliver(&self) -> result::Result<(), std::io::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct HotPlugNotificationFlags: u8 {
|
pub struct HotPlugNotificationFlags: u8 {
|
||||||
const NO_DEVICES_CHANGED = 0;
|
const NO_DEVICES_CHANGED = 0;
|
||||||
|
@ -191,32 +191,6 @@ pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
|
|||||||
|
|
||||||
type VirtioDeviceArc = Arc<Mutex<dyn vm_virtio::VirtioDevice>>;
|
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) {
|
pub fn get_win_size() -> (u16, u16) {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct WS {
|
struct WS {
|
||||||
@ -486,9 +460,9 @@ impl DeviceManager {
|
|||||||
let ged_notification_device = DeviceManager::add_acpi_devices(
|
let ged_notification_device = DeviceManager::add_acpi_devices(
|
||||||
vm_info,
|
vm_info,
|
||||||
&address_manager,
|
&address_manager,
|
||||||
|
&interrupt_manager,
|
||||||
reset_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
|
reset_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
|
||||||
_exit_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
|
_exit_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
|
||||||
&ioapic,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if cfg!(feature = "pci_support") {
|
if cfg!(feature = "pci_support") {
|
||||||
@ -708,9 +682,9 @@ impl DeviceManager {
|
|||||||
fn add_acpi_devices(
|
fn add_acpi_devices(
|
||||||
vm_info: &VmInfo,
|
vm_info: &VmInfo,
|
||||||
address_manager: &Arc<AddressManager>,
|
address_manager: &Arc<AddressManager>,
|
||||||
|
interrupt_manager: &Arc<dyn InterruptManager>,
|
||||||
reset_evt: EventFd,
|
reset_evt: EventFd,
|
||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
ioapic: &Arc<Mutex<ioapic::Ioapic>>,
|
|
||||||
) -> DeviceManagerResult<Option<Arc<Mutex<devices::AcpiGEDDevice>>>> {
|
) -> DeviceManagerResult<Option<Arc<Mutex<devices::AcpiGEDDevice>>>> {
|
||||||
let acpi_device = Arc::new(Mutex::new(devices::AcpiShutdownDevice::new(
|
let acpi_device = Arc::new(Mutex::new(devices::AcpiShutdownDevice::new(
|
||||||
exit_evt, reset_evt,
|
exit_evt, reset_evt,
|
||||||
@ -734,10 +708,15 @@ impl DeviceManager {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate_irq()
|
.allocate_irq()
|
||||||
.unwrap();
|
.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
|
address_manager
|
||||||
.allocator
|
.allocator
|
||||||
|
Loading…
Reference in New Issue
Block a user