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;