From 442e7f85fac77ffe60270892d29678fec03579d7 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 4 May 2026 22:08:24 +0200 Subject: [PATCH] virtio-devices: Test trigger with OOB MSI-X vector does not panic Verify that firing an interrupt with a queue vector beyond the MSI-X table size returns Ok without panicking. Signed-off-by: Anatol Belski --- virtio-devices/src/transport/pci_device.rs | 63 ++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/virtio-devices/src/transport/pci_device.rs b/virtio-devices/src/transport/pci_device.rs index dc71be40d..b8b3b6835 100644 --- a/virtio-devices/src/transport/pci_device.rs +++ b/virtio-devices/src/transport/pci_device.rs @@ -1323,3 +1323,66 @@ impl Snapshottable for VirtioPciDevice { } impl Transportable for VirtioPciDevice {} impl Migratable for VirtioPciDevice {} + +#[cfg(test)] +mod unit_tests { + use vm_device::interrupt::InterruptSourceConfig; + + use super::*; + + struct TestInterruptSourceGroup { + event_fd: EventFd, + } + + impl InterruptSourceGroup for TestInterruptSourceGroup { + fn trigger(&self, _index: InterruptIndex) -> std::result::Result<(), std::io::Error> { + self.event_fd.write(1) + } + fn notifier(&self, _index: InterruptIndex) -> Option { + Some(self.event_fd.try_clone().unwrap()) + } + fn update( + &self, + _index: InterruptIndex, + _config: InterruptSourceConfig, + _masked: bool, + _set_gsi: bool, + ) -> std::result::Result<(), std::io::Error> { + Ok(()) + } + fn set_gsi(&self) -> std::result::Result<(), std::io::Error> { + Ok(()) + } + } + + fn make_msix_interrupt(num_vectors: u16) -> VirtioInterruptMsix { + let isg = Arc::new(TestInterruptSourceGroup { + event_fd: EventFd::new(0).unwrap(), + }); + let msix_config = Arc::new(Mutex::new( + MsixConfig::new( + num_vectors, + MaybeMutInterruptSourceGroup::Immutable(isg.clone()), + 0, + None, + ) + .unwrap(), + )); + let config_vector = Arc::new(AtomicU16::new(VIRTQ_MSI_NO_VECTOR)); + let queues_vectors = Arc::new(Mutex::new(vec![VIRTQ_MSI_NO_VECTOR; 1])); + + VirtioInterruptMsix::new( + msix_config, + config_vector, + queues_vectors, + MaybeMutInterruptSourceGroup::Immutable(isg), + ) + } + + #[test] + fn trigger_with_oob_vector_does_not_panic() { + let intr = make_msix_interrupt(2); + intr.queues_vectors.lock().unwrap()[0] = 0xFFFE; + intr.trigger(VirtioInterruptType::Queue(0)).unwrap(); + } +}