From 8e5c7a37b9c88f37a16e8e266ad52b96d36a8a41 Mon Sep 17 00:00:00 2001 From: Jinank Jain Date: Fri, 23 Aug 2024 21:56:08 +0530 Subject: [PATCH] vm-virtio: Add helper function to get size of virtqueue segments This would be used in case of SEV-SNP guest because we need to accquire access to these virtqueue segments before accessing them. Signed-off-by: Jinank Jain --- .../src/transport/pci_common_config.rs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/virtio-devices/src/transport/pci_common_config.rs b/virtio-devices/src/transport/pci_common_config.rs index 2e78b13c0..a741f580a 100644 --- a/virtio-devices/src/transport/pci_common_config.rs +++ b/virtio-devices/src/transport/pci_common_config.rs @@ -28,6 +28,72 @@ pub struct VirtioPciCommonConfigState { pub msix_queues: Vec, } +/* The standard layout for the ring is a continuous chunk of memory which looks + * like this. We assume num is a power of 2. + * + * struct vring + * { + * // The actual descriptors (16 bytes each) + * struct vring_desc desc[num]; + * + * // A ring of available descriptor heads with free-running index. + * __virtio16 avail_flags; + * __virtio16 avail_idx; + * __virtio16 available[num]; + * __virtio16 used_event_idx; + * + * // Padding to the next align boundary. + * char pad[]; + * + * // A ring of used descriptor heads with free-running index. + * __virtio16 used_flags; + * __virtio16 used_idx; + * struct vring_used_elem used[num]; + * __virtio16 avail_event_idx; + * }; + * struct vring_desc { + * __virtio64 addr; + * __virtio32 len; + * __virtio16 flags; + * __virtio16 next; + * }; + * + * struct vring_avail { + * __virtio16 flags; + * __virtio16 idx; + * __virtio16 ring[]; + * }; + * + * // u32 is used here for ids for padding reasons. + * struct vring_used_elem { + * // Index of start of used descriptor chain. + * __virtio32 id; + * // Total length of the descriptor chain which was used (written to) + * __virtio32 len; + * }; +* + * Kernel header used for this reference: include/uapi/linux/virtio_ring.h + * Virtio Spec: https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html + * + */ +const VRING_DESC_ELEMENT_SIZE: usize = 16; +const VRING_AVAIL_ELEMENT_SIZE: usize = 2; +const VRING_USED_ELEMENT_SIZE: usize = 8; +pub enum VringType { + Desc, + Avail, + Used, +} + +pub fn get_vring_size(t: VringType, queue_size: u16) -> u64 { + let (length_except_ring, element_size) = match t { + VringType::Desc => (0, VRING_DESC_ELEMENT_SIZE), + VringType::Avail => (6, VRING_AVAIL_ELEMENT_SIZE), + VringType::Used => (6, VRING_USED_ELEMENT_SIZE), + }; + (length_except_ring + element_size * queue_size as usize) as u64 +} + /// Contains the data for reading and writing the common configuration structure of a virtio PCI /// device. ///