summary refs log tree commit diff
path: root/devices/src/virtio/descriptor_utils.rs
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2019-07-25 10:26:41 -0700
committerCommit Bot <commit-bot@chromium.org>2019-08-13 16:48:43 +0000
commit1765e6f80f48f5fc6081af1306b28c24723d623f (patch)
treed3d9466b0ac8f8730a78051d1b330ef688c979ce /devices/src/virtio/descriptor_utils.rs
parent977f008bc3be607600a98d77ef6984b52dba7eb6 (diff)
downloadcrosvm-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/virtio/descriptor_utils.rs')
-rw-r--r--devices/src/virtio/descriptor_utils.rs52
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()