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}