mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-04 04:25:45 +00:00
vmm: Use LegacyUserspaceInterruptGroup for mmio devices
This commit replaces the way legacy interrupts were handled with the brand new implementation of the legacy InterruptSourceGroup for KVM. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
12657ef59f
commit
8d7c4ea334
@ -10,11 +10,12 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use devices::{BusDevice, Interrupt};
|
use devices::BusDevice;
|
||||||
use libc::EFD_NONBLOCK;
|
use libc::EFD_NONBLOCK;
|
||||||
use std::result;
|
use std::result;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use vm_device::interrupt::InterruptSourceGroup;
|
||||||
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
|
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
|
||||||
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||||
use vmm_sys_util::{errno::Result, eventfd::EventFd};
|
use vmm_sys_util::{errno::Result, eventfd::EventFd};
|
||||||
@ -26,11 +27,14 @@ const MMIO_VERSION: u32 = 2;
|
|||||||
|
|
||||||
pub struct VirtioInterruptIntx {
|
pub struct VirtioInterruptIntx {
|
||||||
interrupt_status: Arc<AtomicUsize>,
|
interrupt_status: Arc<AtomicUsize>,
|
||||||
interrupt: Box<dyn Interrupt>,
|
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VirtioInterruptIntx {
|
impl VirtioInterruptIntx {
|
||||||
pub fn new(interrupt_status: Arc<AtomicUsize>, interrupt: Box<dyn Interrupt>) -> Self {
|
pub fn new(
|
||||||
|
interrupt_status: Arc<AtomicUsize>,
|
||||||
|
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
|
||||||
|
) -> Self {
|
||||||
VirtioInterruptIntx {
|
VirtioInterruptIntx {
|
||||||
interrupt_status,
|
interrupt_status,
|
||||||
interrupt,
|
interrupt,
|
||||||
@ -51,7 +55,7 @@ impl VirtioInterrupt for VirtioInterruptIntx {
|
|||||||
self.interrupt_status
|
self.interrupt_status
|
||||||
.fetch_or(status as usize, Ordering::SeqCst);
|
.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<dyn Interrupt>) {
|
pub fn assign_interrupt(&mut self, interrupt: Arc<Box<dyn InterruptSourceGroup>>) {
|
||||||
self.interrupt_cb = Some(Arc::new(VirtioInterruptIntx::new(
|
self.interrupt_cb = Some(Arc::new(VirtioInterruptIntx::new(
|
||||||
self.interrupt_status.clone(),
|
self.interrupt_status.clone(),
|
||||||
interrupt,
|
interrupt,
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
extern crate vm_device;
|
extern crate vm_device;
|
||||||
|
|
||||||
use crate::config::{ConsoleOutputMode, VmConfig};
|
use crate::config::{ConsoleOutputMode, VmConfig};
|
||||||
#[cfg(feature = "pci_support")]
|
|
||||||
use crate::interrupt::{KvmInterruptManager, KvmRoutingEntry};
|
use crate::interrupt::{KvmInterruptManager, KvmRoutingEntry};
|
||||||
use crate::memory_manager::{Error as MemoryManagerError, MemoryManager};
|
use crate::memory_manager::{Error as MemoryManagerError, MemoryManager};
|
||||||
use crate::vm::VmInfo;
|
use crate::vm::VmInfo;
|
||||||
@ -30,7 +29,6 @@ use pci::{
|
|||||||
DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot,
|
DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot,
|
||||||
};
|
};
|
||||||
use qcow::{self, ImageType, QcowFile};
|
use qcow::{self, ImageType, QcowFile};
|
||||||
#[cfg(feature = "pci_support")]
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::io::{self, sink, stdout};
|
use std::io::{self, sink, stdout};
|
||||||
@ -44,8 +42,9 @@ use std::sync::{Arc, Mutex};
|
|||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError};
|
use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError};
|
||||||
use vm_allocator::SystemAllocator;
|
use vm_allocator::SystemAllocator;
|
||||||
#[cfg(feature = "pci_support")]
|
|
||||||
use vm_device::interrupt::InterruptManager;
|
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_device::{Migratable, MigratableError, Pausable, Snapshotable};
|
||||||
use vm_memory::GuestAddress;
|
use vm_memory::GuestAddress;
|
||||||
use vm_memory::{Address, GuestMemoryMmap, GuestUsize};
|
use vm_memory::{Address, GuestMemoryMmap, GuestUsize};
|
||||||
@ -182,15 +181,17 @@ pub enum DeviceManagerError {
|
|||||||
|
|
||||||
// Error from a memory manager operation
|
// Error from a memory manager operation
|
||||||
MemoryManager(MemoryManagerError),
|
MemoryManager(MemoryManagerError),
|
||||||
|
|
||||||
|
/// Failed to create new interrupt source group.
|
||||||
|
CreateInterruptGroup(io::Error),
|
||||||
|
|
||||||
|
/// Failed to update interrupt source group.
|
||||||
|
UpdateInterruptGroup(io::Error),
|
||||||
}
|
}
|
||||||
pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
|
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 InterruptInfo<'a> {
|
|
||||||
_ioapic: &'a Arc<Mutex<ioapic::Ioapic>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct UserIoapicIrq {
|
struct UserIoapicIrq {
|
||||||
ioapic: Arc<Mutex<ioapic::Ioapic>>,
|
ioapic: Arc<Mutex<ioapic::Ioapic>>,
|
||||||
irq: usize,
|
irq: usize,
|
||||||
@ -445,7 +446,6 @@ impl DeviceManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let ioapic = DeviceManager::add_ioapic(vm_info, &address_manager)?;
|
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
|
// 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,
|
// devices. This way, we can maintain the full list of used GSI,
|
||||||
@ -507,7 +507,7 @@ impl DeviceManager {
|
|||||||
vm_info,
|
vm_info,
|
||||||
&address_manager,
|
&address_manager,
|
||||||
virtio_devices,
|
virtio_devices,
|
||||||
&interrupt_info,
|
&interrupt_manager,
|
||||||
&mut cmdline_additions,
|
&mut cmdline_additions,
|
||||||
&mut migratable_devices,
|
&mut migratable_devices,
|
||||||
)?;
|
)?;
|
||||||
@ -654,7 +654,7 @@ impl DeviceManager {
|
|||||||
vm_info: &VmInfo,
|
vm_info: &VmInfo,
|
||||||
address_manager: &Arc<AddressManager>,
|
address_manager: &Arc<AddressManager>,
|
||||||
virtio_devices: Vec<(Arc<Mutex<dyn vm_virtio::VirtioDevice>>, bool)>,
|
virtio_devices: Vec<(Arc<Mutex<dyn vm_virtio::VirtioDevice>>, bool)>,
|
||||||
interrupt_info: &InterruptInfo,
|
interrupt_manager: &Arc<dyn InterruptManager>,
|
||||||
mut cmdline_additions: &mut Vec<String>,
|
mut cmdline_additions: &mut Vec<String>,
|
||||||
migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>,
|
migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>,
|
||||||
) -> DeviceManagerResult<()> {
|
) -> DeviceManagerResult<()> {
|
||||||
@ -672,7 +672,7 @@ impl DeviceManager {
|
|||||||
vm_info.memory,
|
vm_info.memory,
|
||||||
&address_manager,
|
&address_manager,
|
||||||
vm_info.vm_fd,
|
vm_info.vm_fd,
|
||||||
&interrupt_info,
|
interrupt_manager,
|
||||||
addr,
|
addr,
|
||||||
&mut cmdline_additions,
|
&mut cmdline_additions,
|
||||||
migratable_devices,
|
migratable_devices,
|
||||||
@ -1526,7 +1526,7 @@ impl DeviceManager {
|
|||||||
memory: &Arc<ArcSwap<GuestMemoryMmap>>,
|
memory: &Arc<ArcSwap<GuestMemoryMmap>>,
|
||||||
address_manager: &Arc<AddressManager>,
|
address_manager: &Arc<AddressManager>,
|
||||||
vm_fd: &Arc<VmFd>,
|
vm_fd: &Arc<VmFd>,
|
||||||
interrupt_info: &InterruptInfo,
|
interrupt_manager: &Arc<dyn InterruptManager>,
|
||||||
mmio_base: GuestAddress,
|
mmio_base: GuestAddress,
|
||||||
cmdline_additions: &mut Vec<String>,
|
cmdline_additions: &mut Vec<String>,
|
||||||
migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>,
|
migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>,
|
||||||
@ -1548,12 +1548,11 @@ impl DeviceManager {
|
|||||||
.allocate_irq()
|
.allocate_irq()
|
||||||
.ok_or(DeviceManagerError::AllocateIrq)?;
|
.ok_or(DeviceManagerError::AllocateIrq)?;
|
||||||
|
|
||||||
let interrupt: Box<dyn devices::Interrupt> = Box::new(UserIoapicIrq::new(
|
let interrupt_group = interrupt_manager
|
||||||
interrupt_info._ioapic.clone(),
|
.create_group(PIN_IRQ, irq_num as InterruptIndex, 1 as InterruptIndex)
|
||||||
irq_num as usize,
|
.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));
|
let mmio_device_arc = Arc::new(Mutex::new(mmio_device));
|
||||||
address_manager
|
address_manager
|
||||||
|
Loading…
Reference in New Issue
Block a user