Alioth Code Coverage

virtio.rs0.00%

1// Copyright 2024 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#[path = "dev/dev.rs"]
16pub mod dev;
17pub mod pci;
18#[path = "queue/queue.rs"]
19pub mod queue;
20#[cfg(target_os = "linux")]
21pub mod vhost;
22#[cfg(target_os = "linux")]
23#[path = "vu/vu.rs"]
24pub mod vu;
25#[path = "worker/worker.rs"]
26pub mod worker;
27
28use std::fmt::Debug;
29use std::os::fd::BorrowedFd;
30use std::path::Path;
31
32use snafu::Snafu;
33
34use crate::errors::{DebugTrace, trace_error};
35use crate::{bitflags, consts};
36
37#[trace_error]
38#[derive(Snafu, DebugTrace)]
39#[snafu(module, context(suffix(false)))]
40pub enum Error {
41 #[snafu(display("Hypervisor internal error"), context(false))]
42 HvError { source: Box<crate::hv::Error> },
43 #[snafu(display("Failed to access guest memory"), context(false))]
44 Memory { source: Box<crate::mem::Error> },
45 #[snafu(display("PCI bus error"), context(false))]
46 PciBus { source: crate::pci::Error },
47 #[snafu(display("Cannot access file {path:?}"))]
48 AccessFile {
49 path: Box<Path>,
50 error: std::io::Error,
51 },
52 #[snafu(display("Failed to lock file {path:?}"))]
53 LockFile {
54 path: Box<Path>,
55 error: std::fs::TryLockError,
56 },
57 #[snafu(display("Error from OS"), context(false))]
58 System { error: std::io::Error },
59 #[snafu(display("Failed to create a poll"))]
60 CreatePoll { error: std::io::Error },
61 #[snafu(display("Failed to register/deregister an event source"))]
62 EventSource { error: std::io::Error },
63 #[snafu(display("Failed to poll events"))]
64 PollEvents { error: std::io::Error },
65 #[snafu(display("Failed to create a worker thread"))]
66 WorkerThread { error: std::io::Error },
67 #[snafu(display("Invalid descriptor id {id}"))]
68 InvalidDescriptor { id: u16 },
69 #[snafu(display("Invalid queue index {index}"))]
70 InvalidQueueIndex { index: u16 },
71 #[snafu(display("Invalid msix vector {vector}"))]
72 InvalidMsixVector { vector: u16 },
73 #[snafu(display("Invalid virtq buffer"))]
74 InvalidBuffer,
75 #[cfg(target_os = "linux")]
76 #[snafu(display("vhost-user error"), context(false))]
77 Vu { source: Box<vu::Error> },
78 #[cfg(target_os = "linux")]
79 #[snafu(display("vhost error"), context(false))]
80 Vhost { source: Box<vhost::Error> },
81 #[snafu(display("fuse error"), context(false))]
82 Fuse { source: Box<crate::fuse::Error> },
83}
84
85type Result<T, E = Error> = std::result::Result<T, E>;
86
87bitflags! {
88 pub struct VirtioFeature(u128) {
89 INDIRECT_DESC = 1 << 28;
90 EVENT_IDX = 1 << 29;
91 VHOST_PROTOCOL = 1 << 30;
92 VERSION_1 = 1 << 32;
93 ACCESS_PLATFORM = 1 << 33;
94 RING_PACKED = 1 << 34;
95 }
96}
97
98const FEATURE_BUILT_IN: u128 = VirtioFeature::EVENT_IDX.bits()
99 | VirtioFeature::RING_PACKED.bits()
100 | VirtioFeature::VERSION_1.bits();
101
102consts! {
103 pub struct DeviceId(u16) {
104 NET = 1;
105 BLOCK = 2;
106 ENTROPY = 4;
107 BALLOON = 5;
108 SOCKET = 19;
109 IOMMU = 23;
110 MEM = 24;
111 FILE_SYSTEM = 26;
112 PMEM = 27;
113 }
114}
115
116bitflags! {
117 #[derive(Default)]
118 pub struct DevStatus(u8) {
119 ACK = 1 << 0;
120 DRIVER = 1 << 1;
121 DRIVER_OK = 1 << 2;
122 FEATURES_OK = 1 << 3;
123 NEEDS_RESET = 1 << 6;
124 FAILED = 1 << 7;
125 }
126}
127
128pub trait IrqSender: Send + Sync + Debug + 'static {
129 fn queue_irq(&self, idx: u16);
130 fn config_irq(&self);
131 fn queue_irqfd<F, T>(&self, idx: u16, f: F) -> Result<T>
132 where
133 F: FnOnce(BorrowedFd) -> Result<T>;
134 fn config_irqfd<F, T>(&self, f: F) -> Result<T>
135 where
136 F: FnOnce(BorrowedFd) -> Result<T>;
137}
138
139#[cfg(test)]
140#[path = "virtio_test.rs"]
141mod tests;
142