diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2019-09-19 11:23:46 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-05 19:26:37 +0000 |
commit | 102278e944dcdc9a489a41644a53c225d8985380 (patch) | |
tree | 539cba723f143a34f33b5b2351bd4117d81cfa30 /devices/src/virtio/descriptor_utils.rs | |
parent | 21556bf5d8dbf49f9aa29782a96e12b5579e5e58 (diff) | |
download | crosvm-102278e944dcdc9a489a41644a53c225d8985380.tar crosvm-102278e944dcdc9a489a41644a53c225d8985380.tar.gz crosvm-102278e944dcdc9a489a41644a53c225d8985380.tar.bz2 crosvm-102278e944dcdc9a489a41644a53c225d8985380.tar.lz crosvm-102278e944dcdc9a489a41644a53c225d8985380.tar.xz crosvm-102278e944dcdc9a489a41644a53c225d8985380.tar.zst crosvm-102278e944dcdc9a489a41644a53c225d8985380.zip |
devices: add into_iovec() for DescriptorUtils
This allows the conversion of (part of) a descriptor chain into an iovec suitable for use with sys_util functions like send_with_fds(). BUG=None TEST=./build_test.py Change-Id: I4e3f7d9c1175c1173661b0661d3fa15d1da72d1a Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1815417 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices/src/virtio/descriptor_utils.rs')
-rw-r--r-- | devices/src/virtio/descriptor_utils.rs | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/devices/src/virtio/descriptor_utils.rs b/devices/src/virtio/descriptor_utils.rs index 0c228ed..00c52c9 100644 --- a/devices/src/virtio/descriptor_utils.rs +++ b/devices/src/virtio/descriptor_utils.rs @@ -6,12 +6,15 @@ use std::cmp; use std::collections::VecDeque; use std::fmt::{self, Display}; use std::io::{self, Read, Write}; +use std::marker::PhantomData; use std::mem::{size_of, MaybeUninit}; use std::ptr::copy_nonoverlapping; use std::result; use data_model::{DataInit, Le16, Le32, Le64, VolatileMemory, VolatileMemoryError, VolatileSlice}; -use sys_util::{FileReadWriteAtVolatile, FileReadWriteVolatile, GuestAddress, GuestMemory}; +use sys_util::{ + FileReadWriteAtVolatile, FileReadWriteVolatile, GuestAddress, GuestMemory, IntoIovec, +}; use super::DescriptorChain; @@ -177,6 +180,27 @@ impl<'a> DescriptorChainConsumer<'a> { Err(Error::SplitOutOfBounds(offset)) } } + + fn get_iovec(&mut self, len: usize) -> io::Result<DescriptorIovec<'a>> { + let mut iovec = Vec::new(); + + self.consume(len, |bufs| { + let mut total = 0; + for vs in bufs { + iovec.push(libc::iovec { + iov_base: vs.as_ptr() as *mut libc::c_void, + iov_len: vs.size() as usize, + }); + total += vs.size() as usize; + } + Ok(total) + })?; + + Ok(DescriptorIovec { + iovec, + mem: PhantomData, + }) + } } /// Provides high-level interface over the sequence of memory regions @@ -303,6 +327,12 @@ impl<'a> Reader<'a> { pub fn split_at(&mut self, offset: usize) -> Result<Reader<'a>> { self.buffer.split_at(offset).map(|buffer| Reader { buffer }) } + + /// Returns a DescriptorIovec for the next `len` bytes of the descriptor chain + /// buffer, which can be used as an IntoIovec. + pub fn get_iovec(&mut self, len: usize) -> io::Result<DescriptorIovec<'a>> { + self.buffer.get_iovec(len) + } } impl<'a> io::Read for Reader<'a> { @@ -442,6 +472,12 @@ impl<'a> Writer<'a> { pub fn split_at(&mut self, offset: usize) -> Result<Writer<'a>> { self.buffer.split_at(offset).map(|buffer| Writer { buffer }) } + + /// Returns a DescriptorIovec for the next `len` bytes of the descriptor chain + /// buffer, which can be used as an IntoIovec. + pub fn get_iovec(&mut self, len: usize) -> io::Result<DescriptorIovec<'a>> { + self.buffer.get_iovec(len) + } } impl<'a> io::Write for Writer<'a> { @@ -471,6 +507,18 @@ impl<'a> io::Write for Writer<'a> { } } +pub struct DescriptorIovec<'a> { + iovec: Vec<libc::iovec>, + mem: PhantomData<&'a GuestMemory>, +} + +// Safe because the lifetime of DescriptorIovec is tied to the underlying GuestMemory. +unsafe impl<'a> IntoIovec for DescriptorIovec<'a> { + fn into_iovec(&self) -> Vec<libc::iovec> { + self.iovec.clone() + } +} + const VIRTQ_DESC_F_NEXT: u16 = 0x1; const VIRTQ_DESC_F_WRITE: u16 = 0x2; |