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 byteorder::{ByteOrder, LittleEndian};
use kvm_bindings::kvm_msi; use kvm_bindings::kvm_msi;
use kvm_ioctls::VmFd; use kvm_ioctls::VmFd;
use std::io;
use std::result; use std::result;
use std::sync::Arc; use std::sync::Arc;
use vm_device::interrupt::{InterruptIndex, InterruptManager, InterruptSourceGroup, PCI_MSI_IRQ};
use vm_memory::GuestAddress; use vm_memory::GuestAddress;
#[derive(Debug)] #[derive(Debug)]
@ -27,6 +29,8 @@ pub enum Error {
InvalidTriggerMode, InvalidTriggerMode,
/// Invalid delivery mode. /// Invalid delivery mode.
InvalidDeliveryMode, InvalidDeliveryMode,
/// Failed creating the interrupt source group.
CreateInterruptSourceGroup(io::Error),
} }
type Result<T> = result::Result<T, Error>; type Result<T> = result::Result<T, Error>;
@ -158,6 +162,7 @@ pub struct Ioapic {
reg_entries: [RedirectionTableEntry; NUM_IOAPIC_PINS], reg_entries: [RedirectionTableEntry; NUM_IOAPIC_PINS],
vm_fd: Arc<VmFd>, vm_fd: Arc<VmFd>,
apic_address: GuestAddress, apic_address: GuestAddress,
_interrupt_source_group: Arc<Box<dyn InterruptSourceGroup>>,
} }
impl BusDevice for Ioapic { impl BusDevice for Ioapic {
@ -196,14 +201,27 @@ impl BusDevice for Ioapic {
} }
impl Ioapic { impl Ioapic {
pub fn new(vm_fd: Arc<VmFd>, apic_address: GuestAddress) -> Ioapic { pub fn new(
Ioapic { 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, id: 0,
reg_sel: 0, reg_sel: 0,
reg_entries: [0; NUM_IOAPIC_PINS], reg_entries: [0; NUM_IOAPIC_PINS],
vm_fd, vm_fd,
apic_address, apic_address,
} _interrupt_source_group: interrupt_source_group,
})
} }
// The ioapic must be informed about EOIs in order to deassert interrupts // 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. /// Failed to update interrupt source group.
UpdateInterruptGroup(io::Error), UpdateInterruptGroup(io::Error),
/// Failed creating IOAPIC.
CreateIoapic(ioapic::Error),
} }
pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>; pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
@ -697,13 +700,13 @@ impl DeviceManager {
fn add_ioapic( fn add_ioapic(
vm_info: &VmInfo, vm_info: &VmInfo,
address_manager: &Arc<AddressManager>, address_manager: &Arc<AddressManager>,
_ioapic_interrupt_manager: Arc<dyn InterruptManager>, interrupt_manager: Arc<dyn InterruptManager>,
) -> DeviceManagerResult<Arc<Mutex<ioapic::Ioapic>>> { ) -> DeviceManagerResult<Arc<Mutex<ioapic::Ioapic>>> {
// Create IOAPIC // Create IOAPIC
let ioapic = Arc::new(Mutex::new(ioapic::Ioapic::new( let ioapic = Arc::new(Mutex::new(
vm_info.vm_fd.clone(), ioapic::Ioapic::new(vm_info.vm_fd.clone(), APIC_START, interrupt_manager)
APIC_START, .map_err(DeviceManagerError::CreateIoapic)?,
))); ));
address_manager address_manager
.mmio_bus .mmio_bus