vmm/devices/virtio/transport/mod.rs
1// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::sync::Arc;
5use std::sync::atomic::AtomicU32;
6
7use vmm_sys_util::eventfd::EventFd;
8
9use crate::vstate::interrupts::InterruptError;
10
11/// MMIO transport for VirtIO devices
12pub mod mmio;
13/// PCI transport for VirtIO devices
14pub mod pci;
15
16/// Represents the types of interrupts used by VirtIO devices
17#[derive(Debug, Clone)]
18pub enum VirtioInterruptType {
19 /// Interrupt for VirtIO configuration changes
20 Config,
21 /// Interrupts for new events in a queue.
22 Queue(u16),
23}
24
25/// API of interrupt types used by VirtIO devices
26pub trait VirtioInterrupt: std::fmt::Debug + Send + Sync {
27 /// Trigger a VirtIO interrupt.
28 fn trigger(&self, interrupt_type: VirtioInterruptType) -> Result<(), InterruptError>;
29
30 /// Trigger multiple Virtio interrupts for selected queues.
31 /// The caller needs to ensure that [`queues`] does not include duplicate entries to
32 /// avoid sending multiple interrupts for the same queue.
33 /// This is to allow sending a single interrupt for implementations that don't
34 /// distinguish different queues, like IrqTrigger, instead of sending multiple same
35 /// interrupts.
36 fn trigger_queues(&self, queues: &[u16]) -> Result<(), InterruptError> {
37 queues
38 .iter()
39 .try_for_each(|&qidx| self.trigger(VirtioInterruptType::Queue(qidx)))
40 }
41
42 /// Get the `EventFd` (if any) that backs the underlying interrupt.
43 fn notifier(&self, _interrupt_type: VirtioInterruptType) -> Option<&EventFd> {
44 None
45 }
46
47 /// Get the current device interrupt status.
48 fn status(&self) -> Arc<AtomicU32>;
49
50 /// Returns true if there is any pending interrupt
51 #[cfg(test)]
52 fn has_pending_interrupt(&self, interrupt_type: VirtioInterruptType) -> bool;
53
54 /// Used to acknowledge an interrupt
55 #[cfg(test)]
56 fn ack_interrupt(&self, interrupt_type: VirtioInterruptType);
57}