Skip to main content

virtio/transport/
mod.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Run virtio devices over different transports
5
6use crate::MAX_QUEUE_SIZE;
7use chipset_device::io::deferred::DeferredRead;
8use chipset_device::io::deferred::DeferredWrite;
9use std::io;
10
11pub(crate) mod core;
12mod mmio;
13mod pci;
14pub(crate) mod saved_state;
15mod task;
16
17/// An MMIO access that arrived while the transport state machine was busy
18/// (enable or disable in flight).  Stalled accesses are replayed in order
19/// once the in-flight operation completes.
20pub(crate) enum StalledIo {
21    Read {
22        address: u64,
23        len: usize,
24        deferred: DeferredRead,
25    },
26    Write {
27        address: u64,
28        data: [u8; 8],
29        len: usize,
30        deferred: DeferredWrite,
31    },
32}
33
34/// Validate that a queue size returned by a device is acceptable for use by a
35/// transport: non-zero, power of two, and within [`MAX_QUEUE_SIZE`].
36///
37/// Note that only split queues require a power of two size, but since we don't
38/// know which type of queue the guest will select, the default queue size must
39/// be a power of two to be compatible with both packed and split queues.
40fn validate_queue_size(queue_index: u16, size: u16) -> io::Result<()> {
41    if size == 0 || !size.is_power_of_two() || size > MAX_QUEUE_SIZE {
42        return Err(io::Error::new(
43            io::ErrorKind::InvalidInput,
44            format!(
45                "invalid queue size {size} for queue {queue_index}: \
46                 must be a power of two in 1..={MAX_QUEUE_SIZE}"
47            ),
48        ));
49    }
50    Ok(())
51}
52
53pub use mmio::VirtioMmioDevice;
54pub use pci::PciInterruptModel;
55pub use pci::VirtioPciDevice;