diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2019-07-25 10:26:41 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-08-13 16:48:43 +0000 |
commit | 1765e6f80f48f5fc6081af1306b28c24723d623f (patch) | |
tree | d3d9466b0ac8f8730a78051d1b330ef688c979ce /devices/src | |
parent | 977f008bc3be607600a98d77ef6984b52dba7eb6 (diff) | |
download | crosvm-1765e6f80f48f5fc6081af1306b28c24723d623f.tar crosvm-1765e6f80f48f5fc6081af1306b28c24723d623f.tar.gz crosvm-1765e6f80f48f5fc6081af1306b28c24723d623f.tar.bz2 crosvm-1765e6f80f48f5fc6081af1306b28c24723d623f.tar.lz crosvm-1765e6f80f48f5fc6081af1306b28c24723d623f.tar.xz crosvm-1765e6f80f48f5fc6081af1306b28c24723d623f.tar.zst crosvm-1765e6f80f48f5fc6081af1306b28c24723d623f.zip |
devices: virtio: add volatile read/write for desc chains
This will allow streaming data between a FileReadWriteVolatile and the descriptor chain Reader/Writer types. BUG=chromium:990546 TEST=./build_test Change-Id: Idc97ce99dd1cc340444298f705df4f12e339095d Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1721370 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices/src')
-rw-r--r-- | devices/src/virtio/descriptor_utils.rs | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/devices/src/virtio/descriptor_utils.rs b/devices/src/virtio/descriptor_utils.rs index a206002..a065eb1 100644 --- a/devices/src/virtio/descriptor_utils.rs +++ b/devices/src/virtio/descriptor_utils.rs @@ -9,9 +9,9 @@ use std::io; use std::os::unix::io::AsRawFd; use std::result; -use data_model::DataInit; +use data_model::{DataInit, VolatileMemory, VolatileMemoryError}; use sys_util::guest_memory::Error as GuestMemoryError; -use sys_util::{GuestAddress, GuestMemory}; +use sys_util::{FileReadWriteVolatile, GuestAddress, GuestMemory}; use super::DescriptorChain; @@ -19,6 +19,7 @@ use super::DescriptorChain; pub enum Error { GuestMemoryError(sys_util::GuestMemoryError), IoError(io::Error), + VolatileMemoryError(VolatileMemoryError), } impl Display for Error { @@ -28,6 +29,7 @@ impl Display for Error { match self { GuestMemoryError(e) => write!(f, "descriptor guest memory error: {}", e), IoError(e) => write!(f, "descriptor I/O error: {}", e), + VolatileMemoryError(e) => write!(f, "volatile memory error: {}", e), } } } @@ -273,6 +275,29 @@ impl<'a> Reader<'a> { ) } + /// Reads data from the descriptor chain buffer into a FileReadWriteVolatile. + /// Returns the number of bytes read from the descriptor chain buffer. + /// The number of bytes read can be less than `count` if there isn't + /// enough data in the descriptor chain buffer. + pub fn read_to_volatile( + &mut self, + dst: &mut dyn FileReadWriteVolatile, + count: usize, + ) -> Result<usize> { + let mem = self.mem; + self.buffer.consume( + |addr, count| { + let mem_volatile_slice = mem + .get_slice(addr.offset(), count as u64) + .map_err(Error::VolatileMemoryError)?; + dst.write_all_volatile(mem_volatile_slice) + .map_err(Error::IoError)?; + Ok(()) + }, + count, + ) + } + /// Returns number of bytes available for reading. pub fn available_bytes(&mut self) -> usize { self.buffer.available_bytes() @@ -368,6 +393,29 @@ impl<'a> Writer<'a> { ) } + /// Writes data to the descriptor chain buffer from a FileReadWriteVolatile. + /// Returns the number of bytes written to the descriptor chain buffer. + /// The number of bytes written can be less than `count` if + /// there isn't enough data in the descriptor chain buffer. + pub fn write_from_volatile( + &mut self, + src: &mut dyn FileReadWriteVolatile, + count: usize, + ) -> Result<usize> { + let mem = self.mem; + self.buffer.consume( + |addr, count| { + let mem_volatile_slice = mem + .get_slice(addr.offset(), count as u64) + .map_err(Error::VolatileMemoryError)?; + src.read_exact_volatile(mem_volatile_slice) + .map_err(Error::IoError)?; + Ok(()) + }, + count, + ) + } + /// Returns number of bytes already written to the descriptor chain buffer. pub fn bytes_written(&self) -> usize { self.buffer.bytes_consumed() |