diff --git a/vmm/src/interrupt.rs b/vmm/src/interrupt.rs index afc3e2607..ea51dc81b 100644 --- a/vmm/src/interrupt.rs +++ b/vmm/src/interrupt.rs @@ -242,17 +242,29 @@ impl InterruptSourceGroup for MsiInterruptGroup { } } -pub struct LegacyUserspaceInterruptGroup {} +pub struct LegacyUserspaceInterruptGroup { + ioapic: Arc>, + irq: u32, +} impl LegacyUserspaceInterruptGroup { - fn new() -> Self { - LegacyUserspaceInterruptGroup {} + fn new(ioapic: Arc>, irq: u32) -> Self { + LegacyUserspaceInterruptGroup { ioapic, irq } } } impl InterruptSourceGroup for LegacyUserspaceInterruptGroup { fn trigger(&self, _index: InterruptIndex) -> Result<()> { - Ok(()) + self.ioapic + .lock() + .unwrap() + .service_irq(self.irq as usize) + .map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("failed to inject IRQ #{}: {:?}", self.irq, e), + ) + }) } fn update(&self, _index: InterruptIndex, _config: InterruptSourceConfig) -> Result<()> { @@ -264,7 +276,7 @@ pub struct KvmInterruptManager { allocator: Arc>, vm_fd: Arc, gsi_msi_routes: Arc>>, - _ioapic: Arc>, + ioapic: Arc>, } impl KvmInterruptManager { @@ -278,7 +290,7 @@ impl KvmInterruptManager { allocator, vm_fd, gsi_msi_routes, - _ioapic: ioapic, + ioapic, } } } @@ -291,7 +303,19 @@ impl InterruptManager for KvmInterruptManager { count: InterruptIndex, ) -> Result>> { let interrupt_source_group: Arc> = match interrupt_type { - PIN_IRQ => Arc::new(Box::new(LegacyUserspaceInterruptGroup::new())), + PIN_IRQ => { + if count > 1 { + return Err(io::Error::new( + io::ErrorKind::Other, + "Legacy cannot support more than one interrupt", + )); + } + + Arc::new(Box::new(LegacyUserspaceInterruptGroup::new( + self.ioapic.clone(), + base as u32, + ))) + } PCI_MSI_IRQ => { let mut allocator = self.allocator.lock().unwrap(); let mut irq_routes: HashMap =