virtio_queue/desc/
mod.rs

1//! Descriptor types for virtio queue.
2
3use vm_memory::{ByteValued, Le16, Le32, Le64};
4
5pub mod packed;
6pub mod split;
7
8/// a virtio descriptor
9#[deprecated = "Descriptor has been deprecated. Please use RawDescriptor"]
10pub type Descriptor = RawDescriptor;
11
12/// A virtio descriptor's layout constraints with C representation.
13/// This is a unified representation of the memory layout order
14/// for packed descriptors and split descriptors.
15/// This type corresponds to struct virtq_desc, see:
16/// <https://docs.oasis-open.org/virtio/virtio/v1.3/csd01/virtio-v1.3-csd01.html#x1-720008>
17#[repr(C)]
18#[derive(Clone, Copy, Debug, Default)]
19pub struct RawDescriptor(Le64, Le32, Le16, Le16);
20
21// SAFETY: This is safe because `Descriptor` contains only wrappers over POD types and
22// all accesses through safe `vm-memory` API will validate any garbage that could be
23// included in there.
24unsafe impl ByteValued for RawDescriptor {}
25
26impl From<split::Descriptor> for RawDescriptor {
27    fn from(desc: split::Descriptor) -> Self {
28        RawDescriptor(
29            Le64::from(desc.addr().0),
30            Le32::from(desc.len()),
31            Le16::from(desc.flags()),
32            Le16::from(desc.next()),
33        )
34    }
35}
36
37impl From<packed::Descriptor> for RawDescriptor {
38    fn from(desc: packed::Descriptor) -> Self {
39        RawDescriptor(
40            Le64::from(desc.addr().0),
41            Le32::from(desc.len()),
42            Le16::from(desc.id()),
43            Le16::from(desc.flags()),
44        )
45    }
46}
47
48impl From<RawDescriptor> for split::Descriptor {
49    fn from(desc: RawDescriptor) -> split::Descriptor {
50        split::Descriptor::new(desc.0.into(), desc.1.into(), desc.2.into(), desc.3.into())
51    }
52}
53
54impl From<RawDescriptor> for packed::Descriptor {
55    fn from(desc: RawDescriptor) -> packed::Descriptor {
56        packed::Descriptor::new(desc.0.into(), desc.1.into(), desc.2.into(), desc.3.into())
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use vm_memory::{Le16, Le32, Le64};
63
64    use super::{packed, split, RawDescriptor};
65
66    #[test]
67    fn test_desc_from_split() {
68        let split_desc = split::Descriptor::new(1, 2, 3, 4);
69        let desc = RawDescriptor::from(split_desc);
70        assert_eq!(split_desc.addr().0, desc.0);
71        assert_eq!(split_desc.len(), desc.1);
72        assert_eq!(split_desc.flags(), desc.2);
73        assert_eq!(split_desc.next(), desc.3);
74    }
75
76    #[test]
77    fn test_split_from_desc() {
78        let desc = RawDescriptor(Le64::from(1), Le32::from(2), Le16::from(3), Le16::from(4));
79        let split_desc = split::Descriptor::from(desc);
80        assert_eq!(split_desc.addr().0, desc.0);
81        assert_eq!(split_desc.len(), desc.1);
82        assert_eq!(split_desc.flags(), desc.2);
83        assert_eq!(split_desc.next(), desc.3);
84    }
85
86    #[test]
87    fn test_desc_from_packed() {
88        let packed_desc = packed::Descriptor::new(1, 2, 3, 4);
89        let desc = RawDescriptor::from(packed_desc);
90        assert_eq!(packed_desc.addr().0, desc.0);
91        assert_eq!(packed_desc.len(), desc.1);
92        assert_eq!(packed_desc.id(), desc.2);
93        assert_eq!(packed_desc.flags(), desc.3);
94    }
95
96    #[test]
97    fn test_packed_from_desc() {
98        let desc = RawDescriptor(Le64::from(1), Le32::from(2), Le16::from(3), Le16::from(4));
99        let packed_desc = packed::Descriptor::from(desc);
100        assert_eq!(packed_desc.addr().0, desc.0);
101        assert_eq!(packed_desc.len(), desc.1);
102        assert_eq!(packed_desc.id(), desc.2);
103        assert_eq!(packed_desc.flags(), desc.3);
104    }
105}