vm-virtio: queue: Add methods to switch a descriptor context

"DescriptorChain"s are tied to the lifetime of the referenced
GuestMemoryMmap object (for good reasons), but sometimes (i.e., when
processing descriptors from different contexts) we may need to switch
them to point a different GuestMemoryMmap.

Here we introduce the structure DescriptorHead, which holds the data
needed to rebuild a DescriptorChain, the method "get_head" which
returns the DescriptorHead for a DescriptorChain, and the method
"new_from_head", which allows to create a new DescriptorChain with a
DescriptorHead and a new reference to a GuestMemoryMmap.

Signed-off-by: Sergio Lopez <slp@redhat.com>
This commit is contained in:
Sergio Lopez 2020-03-05 14:30:36 +01:00 committed by Rob Bradford
parent 2294c2d2c9
commit 90309b5106

View File

@ -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<Arc<VirtioIommuRemapping>>,
}
/// 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<DescriptorChain<'a>, 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