From 12657ef59f218276740ca0964af6f7f8becd500f Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 20 Jan 2020 11:27:58 +0100 Subject: [PATCH] vmm: Fully implement LegacyUserspaceInterruptGroup Relying on the previous commits, the legacy interrupt implementation can be completed. The IOAPIC handler is used to deliver the interrupt that will be triggered through the trigger() method. Signed-off-by: Sebastien Boeuf --- vmm/src/interrupt.rs | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) 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 =