From 3bd47ffdc169ab65e0efcf821db3a8c5a08f2fc1 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Tue, 9 Feb 2021 08:28:24 +0100 Subject: [PATCH] interrupt: Add a notifier method to the InterruptController Both GIC and IOAPIC must implement a new method notifier() in order to provide the caller with an EventFd corresponding to the IRQ it refers to. This is needed in anticipation for supporting INTx with VFIO PCI devices. Signed-off-by: Sebastien Boeuf --- devices/src/gic.rs | 5 +++++ devices/src/interrupt_controller.rs | 2 ++ devices/src/ioapic.rs | 5 +++++ devices/src/legacy/serial.rs | 3 +++ vm-device/src/interrupt/mod.rs | 6 +----- vmm/src/interrupt.rs | 4 ++++ 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/devices/src/gic.rs b/devices/src/gic.rs index f421ef4a2..319dc8cdb 100644 --- a/devices/src/gic.rs +++ b/devices/src/gic.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use vm_device::interrupt::{ InterruptIndex, InterruptManager, InterruptSourceGroup, MsiIrqGroupConfig, }; +use vmm_sys_util::eventfd::EventFd; type Result = result::Result; @@ -61,4 +62,8 @@ impl InterruptController for Gic { Ok(()) } + + fn notifier(&self, irq: usize) -> Option { + self.interrupt_source_group.notifier(irq as InterruptIndex) + } } diff --git a/devices/src/interrupt_controller.rs b/devices/src/interrupt_controller.rs index fe4f75908..f33b22fa6 100644 --- a/devices/src/interrupt_controller.rs +++ b/devices/src/interrupt_controller.rs @@ -4,6 +4,7 @@ use std::io; use std::result; +use vmm_sys_util::eventfd::EventFd; #[derive(Debug)] pub enum Error { @@ -56,4 +57,5 @@ pub trait InterruptController: Send { fn enable(&self) -> Result<()>; #[cfg(target_arch = "x86_64")] fn end_of_interrupt(&mut self, vec: u8); + fn notifier(&self, irq: usize) -> Option; } diff --git a/devices/src/ioapic.rs b/devices/src/ioapic.rs index 89d8a0bda..89afeeb36 100644 --- a/devices/src/ioapic.rs +++ b/devices/src/ioapic.rs @@ -24,6 +24,7 @@ use vm_migration::{ Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable, Transportable, }; +use vmm_sys_util::eventfd::EventFd; #[derive(Serialize, Deserialize)] #[serde(remote = "GuestAddress")] @@ -405,6 +406,10 @@ impl InterruptController for Ioapic { Ok(()) } + + fn notifier(&self, irq: usize) -> Option { + self.interrupt_source_group.notifier(irq as InterruptIndex) + } } impl Snapshottable for Ioapic { diff --git a/devices/src/legacy/serial.rs b/devices/src/legacy/serial.rs index 945101cd3..c0b39edc0 100644 --- a/devices/src/legacy/serial.rs +++ b/devices/src/legacy/serial.rs @@ -356,6 +356,9 @@ mod tests { ) -> result::Result<(), std::io::Error> { Ok(()) } + fn notifier(&self, _index: InterruptIndex) -> Option { + Some(self.event_fd.try_clone().unwrap()) + } } impl TestInterrupt { diff --git a/vm-device/src/interrupt/mod.rs b/vm-device/src/interrupt/mod.rs index 9aedcfdbf..4f344e395 100644 --- a/vm-device/src/interrupt/mod.rs +++ b/vm-device/src/interrupt/mod.rs @@ -169,11 +169,7 @@ pub trait InterruptSourceGroup: Send + Sync { /// to inject interrupts into a guest, by writing to the file returned /// by this method. #[allow(unused_variables)] - fn notifier(&self, index: InterruptIndex) -> Option { - // One use case of the notifier is to implement vhost user backends. - // For all other implementations we can just return None here. - None - } + fn notifier(&self, index: InterruptIndex) -> Option; /// Update the interrupt source group configuration. /// diff --git a/vmm/src/interrupt.rs b/vmm/src/interrupt.rs index d597597e7..34b1713a2 100644 --- a/vmm/src/interrupt.rs +++ b/vmm/src/interrupt.rs @@ -246,6 +246,10 @@ impl InterruptSourceGroup for LegacyUserspaceInterruptGroup { fn update(&self, _index: InterruptIndex, _config: InterruptSourceConfig) -> Result<()> { Ok(()) } + + fn notifier(&self, _index: InterruptIndex) -> Option { + self.ioapic.lock().unwrap().notifier(self.irq as usize) + } } pub struct LegacyUserspaceInterruptManager {