Skip to main content

virtio_accel_guest/
config.rs

1use virtio_accel_proto::{ConfigError, WireConfig};
2use virtio_accel_transport::{QueueSize, QueueState};
3
4/// Validated protocol configuration and bounded guest tracking limit.
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6pub struct GuestConfig {
7    wire: WireConfig,
8    max_inflight: u16,
9}
10
11impl GuestConfig {
12    /// Validate the device-specific configuration and offered feature bits.
13    ///
14    /// Protocol 1.0 accepts no device-specific transport feature bits, including unknown bits.
15    pub fn new(
16        wire: WireConfig,
17        offered_features: u64,
18        max_inflight: u16,
19    ) -> Result<Self, GuestConfigError> {
20        wire.validate().map_err(GuestConfigError::Wire)?;
21        if offered_features != 0 {
22            return Err(GuestConfigError::Features);
23        }
24        if max_inflight == 0 {
25            return Err(GuestConfigError::InflightLimit);
26        }
27        Ok(Self { wire, max_inflight })
28    }
29
30    /// Validated wire configuration.
31    pub const fn wire(self) -> WireConfig {
32        self.wire
33    }
34
35    /// Maximum requests retained by this client.
36    pub const fn max_inflight(self) -> u16 {
37        self.max_inflight
38    }
39
40    pub(crate) fn validate_queue(self, state: QueueState) -> Result<(), GuestConfigError> {
41        let size = state.size().ok_or(GuestConfigError::QueueNotConfigured)?;
42        if !state.ready() {
43            return Err(GuestConfigError::QueueNotReady);
44        }
45        self.validate_size(size)
46    }
47
48    pub(crate) fn validate_size(self, size: QueueSize) -> Result<(), GuestConfigError> {
49        if self.wire.max_chain_descriptors.get() > size.get() {
50            return Err(GuestConfigError::QueueSize);
51        }
52        if self.max_inflight > size.get() {
53            return Err(GuestConfigError::InflightLimit);
54        }
55        Ok(())
56    }
57}
58
59/// Invalid guest-visible configuration or negotiation result.
60#[derive(Clone, Copy, Debug, PartialEq, Eq)]
61pub enum GuestConfigError {
62    /// Device-specific configuration violates protocol 1.0.
63    Wire(ConfigError),
64    /// Protocol 1.0 cannot accept any offered device-specific feature bit.
65    Features,
66    /// The command queue has no configured size.
67    QueueNotConfigured,
68    /// The command queue is not ready.
69    QueueNotReady,
70    /// The queue is smaller than the advertised descriptor-chain limit.
71    QueueSize,
72    /// The tracking limit is zero or exceeds queue capacity.
73    InflightLimit,
74}