diff --git a/vm-virtio/src/queue.rs b/vm-virtio/src/queue.rs index 5c6532a16..ed28b6384 100644 --- a/vm-virtio/src/queue.rs +++ b/vm-virtio/src/queue.rs @@ -94,6 +94,14 @@ pub struct Descriptor { unsafe impl ByteValued for Descriptor {} +/// A virtio descriptor head, not tied to a GuestMemoryMmap. +pub struct DescriptorHead { + desc_table: GuestAddress, + table_size: u16, + index: u16, + iommu_mapping_cb: Option>, +} + /// A virtio descriptor chain. #[derive(Clone)] pub struct DescriptorChain<'a> { @@ -224,6 +232,34 @@ impl<'a> DescriptorChain<'a> { Ok(chain) } + /// Returns a copy of a descriptor referencing a different GuestMemoryMmap object. + pub fn new_from_head( + mem: &'a GuestMemoryMmap, + head: DescriptorHead, + ) -> Result, Error> { + match DescriptorChain::checked_new( + mem, + head.desc_table, + head.table_size, + head.index, + head.iommu_mapping_cb, + ) { + Some(d) => Ok(d), + None => Err(Error::InvalidChain), + } + } + + /// Returns a DescriptorHead that can be used to build a copy of a descriptor + /// referencing a different GuestMemoryMmap. + pub fn get_head(&self) -> DescriptorHead { + DescriptorHead { + desc_table: self.desc_table, + table_size: self.table_size, + index: self.index, + iommu_mapping_cb: self.iommu_mapping_cb.clone(), + } + } + fn is_valid(&self) -> bool { !(self .mem