ioapic: Create the InterruptSourceGroup from InterruptManager

The interrupt manager is passed to the IOAPIC creation, and the IOAPIC
now creates an InterruptSourceGroup for MSI interrupts based on it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-01-22 22:55:02 +01:00 committed by Rob Bradford
parent 52800a871a
commit 2dca959084
2 changed files with 29 additions and 8 deletions

View File

@ -13,8 +13,10 @@ use crate::BusDevice;
use byteorder::{ByteOrder, LittleEndian};
use kvm_bindings::kvm_msi;
use kvm_ioctls::VmFd;
use std::io;
use std::result;
use std::sync::Arc;
use vm_device::interrupt::{InterruptIndex, InterruptManager, InterruptSourceGroup, PCI_MSI_IRQ};
use vm_memory::GuestAddress;
#[derive(Debug)]
@ -27,6 +29,8 @@ pub enum Error {
InvalidTriggerMode,
/// Invalid delivery mode.
InvalidDeliveryMode,
/// Failed creating the interrupt source group.
CreateInterruptSourceGroup(io::Error),
}
type Result<T> = result::Result<T, Error>;
@ -158,6 +162,7 @@ pub struct Ioapic {
reg_entries: [RedirectionTableEntry; NUM_IOAPIC_PINS],
vm_fd: Arc<VmFd>,
apic_address: GuestAddress,
_interrupt_source_group: Arc<Box<dyn InterruptSourceGroup>>,
}
impl BusDevice for Ioapic {
@ -196,14 +201,27 @@ impl BusDevice for Ioapic {
}
impl Ioapic {
pub fn new(vm_fd: Arc<VmFd>, apic_address: GuestAddress) -> Ioapic {
Ioapic {
pub fn new(
vm_fd: Arc<VmFd>,
apic_address: GuestAddress,
interrupt_manager: Arc<dyn InterruptManager>,
) -> Result<Ioapic> {
let interrupt_source_group = interrupt_manager
.create_group(
PCI_MSI_IRQ,
0 as InterruptIndex,
NUM_IOAPIC_PINS as InterruptIndex,
)
.map_err(Error::CreateInterruptSourceGroup)?;
Ok(Ioapic {
id: 0,
reg_sel: 0,
reg_entries: [0; NUM_IOAPIC_PINS],
vm_fd,
apic_address,
}
_interrupt_source_group: interrupt_source_group,
})
}
// The ioapic must be informed about EOIs in order to deassert interrupts

View File

@ -189,6 +189,9 @@ pub enum DeviceManagerError {
/// Failed to update interrupt source group.
UpdateInterruptGroup(io::Error),
/// Failed creating IOAPIC.
CreateIoapic(ioapic::Error),
}
pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
@ -697,13 +700,13 @@ impl DeviceManager {
fn add_ioapic(
vm_info: &VmInfo,
address_manager: &Arc<AddressManager>,
_ioapic_interrupt_manager: Arc<dyn InterruptManager>,
interrupt_manager: Arc<dyn InterruptManager>,
) -> DeviceManagerResult<Arc<Mutex<ioapic::Ioapic>>> {
// Create IOAPIC
let ioapic = Arc::new(Mutex::new(ioapic::Ioapic::new(
vm_info.vm_fd.clone(),
APIC_START,
)));
let ioapic = Arc::new(Mutex::new(
ioapic::Ioapic::new(vm_info.vm_fd.clone(), APIC_START, interrupt_manager)
.map_err(DeviceManagerError::CreateIoapic)?,
));
address_manager
.mmio_bus