devices/virtio/
device_constants.rs

1// Copyright 2022 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Contains constants and struct definitions used for implementing vhost-user
6//! frontend devices without compile-time dependencies on their corresponding
7//! backend devices.
8
9use data_model::Le16;
10use data_model::Le32;
11use data_model::Le64;
12use serde::Deserialize;
13use serde::Serialize;
14use zerocopy::FromBytes;
15use zerocopy::Immutable;
16use zerocopy::IntoBytes;
17use zerocopy::KnownLayout;
18
19/// Virtio feature bits that are specific to a device type.
20///
21/// Per virtio 1.2 spec, features 0 to 23 and 50 to 127 are feature bits for the specific device
22/// type. Features beyond 63 are not representable in the current `u64` type used to store sets of
23/// features, so bits 64 to 127 are not included in this mask.
24pub const VIRTIO_DEVICE_TYPE_SPECIFIC_FEATURES_MASK: u64 = 0xfffc_0000_00ff_ffff;
25
26pub mod block {
27    use super::*;
28
29    pub const VIRTIO_BLK_T_IN: u32 = 0;
30    pub const VIRTIO_BLK_T_OUT: u32 = 1;
31    pub const VIRTIO_BLK_T_FLUSH: u32 = 4;
32    pub const VIRTIO_BLK_T_GET_ID: u32 = 8;
33    pub const VIRTIO_BLK_T_DISCARD: u32 = 11;
34    pub const VIRTIO_BLK_T_WRITE_ZEROES: u32 = 13;
35
36    pub const VIRTIO_BLK_S_OK: u8 = 0;
37    pub const VIRTIO_BLK_S_IOERR: u8 = 1;
38    pub const VIRTIO_BLK_S_UNSUPP: u8 = 2;
39
40    pub const VIRTIO_BLK_F_SEG_MAX: u32 = 2;
41    pub const VIRTIO_BLK_F_RO: u32 = 5;
42    pub const VIRTIO_BLK_F_BLK_SIZE: u32 = 6;
43    pub const VIRTIO_BLK_F_FLUSH: u32 = 9;
44    pub const VIRTIO_BLK_F_MQ: u32 = 12;
45    pub const VIRTIO_BLK_F_DISCARD: u32 = 13;
46    pub const VIRTIO_BLK_F_WRITE_ZEROES: u32 = 14;
47
48    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
49    #[repr(C)]
50    pub struct virtio_blk_geometry {
51        cylinders: Le16,
52        heads: u8,
53        sectors: u8,
54    }
55
56    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
57    #[repr(C)]
58    pub struct virtio_blk_topology {
59        physical_block_exp: u8,
60        alignment_offset: u8,
61        min_io_size: Le16,
62        opt_io_size: Le32,
63    }
64
65    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
66    #[repr(C, packed)]
67    pub struct virtio_blk_config {
68        pub capacity: Le64,
69        pub size_max: Le32,
70        pub seg_max: Le32,
71        pub geometry: virtio_blk_geometry,
72        pub blk_size: Le32,
73        pub topology: virtio_blk_topology,
74        pub writeback: u8,
75        pub unused0: u8,
76        pub num_queues: Le16,
77        pub max_discard_sectors: Le32,
78        pub max_discard_seg: Le32,
79        pub discard_sector_alignment: Le32,
80        pub max_write_zeroes_sectors: Le32,
81        pub max_write_zeroes_seg: Le32,
82        pub write_zeroes_may_unmap: u8,
83        pub unused1: [u8; 3],
84    }
85
86    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
87    #[repr(C)]
88    pub struct virtio_blk_req_header {
89        pub req_type: Le32,
90        pub reserved: Le32,
91        pub sector: Le64,
92    }
93
94    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
95    #[repr(C)]
96    pub struct virtio_blk_discard_write_zeroes {
97        pub sector: Le64,
98        pub num_sectors: Le32,
99        pub flags: Le32,
100    }
101
102    pub const VIRTIO_BLK_DISCARD_WRITE_ZEROES_FLAG_UNMAP: u32 = 1 << 0;
103}
104
105pub mod fs {
106    /// The maximum allowable length of the tag used to identify a specific virtio-fs device.
107    pub const FS_MAX_TAG_LEN: usize = 36;
108}
109
110pub mod gpu {
111    use super::*;
112
113    pub const NUM_QUEUES: usize = 2;
114
115    pub const VIRTIO_GPU_F_VIRGL: u32 = 0;
116    pub const VIRTIO_GPU_F_EDID: u32 = 1;
117    pub const VIRTIO_GPU_F_RESOURCE_UUID: u32 = 2;
118    pub const VIRTIO_GPU_F_RESOURCE_BLOB: u32 = 3;
119    pub const VIRTIO_GPU_F_CONTEXT_INIT: u32 = 4;
120    pub const VIRTIO_GPU_F_BLOB_ALIGNMENT: u32 = 5;
121    // The following capabilities are not upstreamed.
122    //
123    // F_CREATE_GUEST_HANDLE is useful for zero-copy memory mappings on certain hypervisors
124    // that are designed around static allocation of guest memory such as Xen.
125    //
126    // Please see https://github.com/magma-gpu/rutabaga_gfx/issues/66 for a discussion and
127    // tracking bug.
128    //
129    // Also, see the following link for the virtio proposal and a link to kernel driver patches:
130    // https://lore.kernel.org/virtio-comment/20260903021442.423274-1-val@invisiblethingslab.com/T/
131    pub const VIRTIO_GPU_F_CREATE_GUEST_HANDLE: u32 = 16;
132
133    pub const VIRTIO_GPU_SHM_ID_HOST_VISIBLE: u8 = 0x0001;
134
135    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
136    #[repr(C)]
137    pub struct virtio_gpu_config {
138        pub events_read: Le32,
139        pub events_clear: Le32,
140        pub num_scanouts: Le32,
141        pub num_capsets: Le32,
142    }
143}
144
145pub mod snd {
146    use super::*;
147
148    #[derive(
149        Copy,
150        Clone,
151        Default,
152        FromBytes,
153        Immutable,
154        IntoBytes,
155        KnownLayout,
156        Serialize,
157        Deserialize,
158        PartialEq,
159        Eq,
160        Debug,
161    )]
162    #[repr(C, packed)]
163    pub struct virtio_snd_config {
164        pub jacks: Le32,
165        pub streams: Le32,
166        pub chmaps: Le32,
167        pub controls: Le32,
168    }
169}
170
171pub mod media {
172    const QUEUE_SIZE: u16 = 256;
173    pub const QUEUE_SIZES: &[u16] = &[QUEUE_SIZE, QUEUE_SIZE];
174}
175
176pub mod video {
177    use data_model::Le32;
178    use serde::Deserialize;
179    use serde::Serialize;
180    use serde_keyvalue::FromKeyValues;
181    use zerocopy::FromBytes;
182    use zerocopy::Immutable;
183    use zerocopy::IntoBytes;
184    use zerocopy::KnownLayout;
185
186    pub const CMD_QUEUE_INDEX: usize = 0;
187    pub const EVENT_QUEUE_INDEX: usize = 1;
188    pub const NUM_QUEUES: usize = 2;
189
190    pub const VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES: u32 = 0;
191    pub const VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG: u32 = 1;
192    pub const VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT: u32 = 2;
193
194    #[derive(Debug, Clone, Copy)]
195    pub enum VideoDeviceType {
196        Decoder,
197        Encoder,
198    }
199
200    #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
201    #[serde(rename_all = "kebab-case")]
202    pub enum VideoBackendType {
203        #[cfg(feature = "libvda")]
204        Libvda,
205        #[cfg(feature = "libvda")]
206        LibvdaVd,
207        #[cfg(feature = "ffmpeg")]
208        Ffmpeg,
209        #[cfg(feature = "vaapi")]
210        Vaapi,
211    }
212
213    #[derive(Debug, Serialize, Deserialize, FromKeyValues)]
214    pub struct VideoDeviceConfig {
215        pub backend: VideoBackendType,
216    }
217
218    /// The same set of virtio features is supported by the ffmpeg decoder and encoder.
219    pub fn ffmpeg_supported_virtio_features() -> u64 {
220        1u64 << VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES
221            | 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG
222            | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
223    }
224
225    /// The same set of virtio features is supported by the vaapi decoder and encoder.
226    pub fn vaapi_supported_virtio_features() -> u64 {
227        1u64 << VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES
228            | 1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG
229            | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
230    }
231
232    /// The same set of virtio features is supported by the vda decoder and encoder.
233    pub fn vda_supported_virtio_features() -> u64 {
234        1u64 << VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG | 1u64 << VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT
235    }
236
237    pub fn backend_supported_virtio_features(backend: VideoBackendType) -> u64 {
238        match backend {
239            #[cfg(feature = "libvda")]
240            VideoBackendType::Libvda | VideoBackendType::LibvdaVd => {
241                vda_supported_virtio_features()
242            }
243            #[cfg(feature = "ffmpeg")]
244            VideoBackendType::Ffmpeg => ffmpeg_supported_virtio_features(),
245            #[cfg(feature = "vaapi")]
246            VideoBackendType::Vaapi => vaapi_supported_virtio_features(),
247        }
248    }
249
250    #[repr(C)]
251    #[derive(Debug, Default, Copy, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
252    pub struct virtio_video_config {
253        pub version: Le32,
254        pub max_caps_length: Le32,
255        pub max_resp_length: Le32,
256        pub device_name: [u8; 32],
257    }
258}
259
260pub mod vsock {
261    pub const NUM_QUEUES: usize = 3;
262}
263
264pub mod wl {
265    pub const NUM_QUEUES: usize = 2;
266
267    pub const VIRTIO_WL_F_TRANS_FLAGS: u32 = 0x01;
268    pub const VIRTIO_WL_F_SEND_FENCES: u32 = 0x02;
269    pub const VIRTIO_WL_F_USE_SHMEM: u32 = 0x03;
270}
271
272pub mod console {
273    use data_model::Le16;
274    use data_model::Le32;
275    use zerocopy::FromBytes;
276    use zerocopy::Immutable;
277    use zerocopy::IntoBytes;
278    use zerocopy::KnownLayout;
279
280    pub const VIRTIO_CONSOLE_F_SIZE: u32 = 0;
281    pub const VIRTIO_CONSOLE_F_MULTIPORT: u32 = 1;
282    pub const VIRTIO_CONSOLE_F_EMERG_WRITE: u32 = 2;
283
284    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
285    #[repr(C)]
286    pub struct virtio_console_config {
287        pub cols: Le16,
288        pub rows: Le16,
289        pub max_nr_ports: Le32,
290        pub emerg_wr: Le32,
291    }
292
293    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
294    #[repr(C)]
295    pub struct virtio_console_control {
296        pub id: Le32,
297        pub event: Le16,
298        pub value: Le16,
299    }
300
301    #[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
302    #[repr(C)]
303    pub struct virtio_console_resize {
304        pub cols: Le16,
305        pub rows: Le16,
306    }
307
308    pub const VIRTIO_CONSOLE_DEVICE_READY: u16 = 0;
309    pub const VIRTIO_CONSOLE_DEVICE_ADD: u16 = 1;
310    pub const VIRTIO_CONSOLE_DEVICE_REMOVE: u16 = 2;
311    pub const VIRTIO_CONSOLE_PORT_READY: u16 = 3;
312    pub const VIRTIO_CONSOLE_CONSOLE_PORT: u16 = 4;
313    pub const VIRTIO_CONSOLE_RESIZE: u16 = 5;
314    pub const VIRTIO_CONSOLE_PORT_OPEN: u16 = 6;
315    pub const VIRTIO_CONSOLE_PORT_NAME: u16 = 7;
316}