From 9cca10a2c0f9a90db6b98cd4349114b3a6350bec Mon Sep 17 00:00:00 2001 From: Bruce Leidl Date: Wed, 11 Sep 2019 15:55:38 -0400 Subject: [PATCH] allow more flexible access to virtqueue chain --- rust/src/virtio/chain.rs | 54 +++++++++++++++++++++++++++++++++++----- rust/src/virtio/vring.rs | 2 +- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/rust/src/virtio/chain.rs b/rust/src/virtio/chain.rs index 6bb62ad..7f2aa54 100644 --- a/rust/src/virtio/chain.rs +++ b/rust/src/virtio/chain.rs @@ -4,6 +4,7 @@ use std::io::{self,Read,Write}; use crate::memory::GuestRam; use super::VirtQueue; use super::vring::Descriptor; +use byteorder::{WriteBytesExt, LittleEndian, ReadBytesExt}; pub struct Chain { @@ -127,7 +128,7 @@ impl Chain { /// load next descriptor if `current` descriptor /// has been fully consumed. /// - fn inc_offset(&mut self, sz: usize) { + pub fn inc_offset(&mut self, sz: usize) { self.offset += sz; if self.offset >= self.current_size() { self.load_next_descriptor(); @@ -225,13 +226,54 @@ impl Chain { res } - /* - pub fn copy_to_writer(&mut self, w: W, size: usize) -> io::Result { - unimplemented!() - + pub fn current_write_slice(&self) -> &mut [u8] { + match self.current { + Some(d) if d.is_write() && d.remaining(self.offset) > 0 => { + let size = d.remaining(self.offset); + self.memory.mut_slice(d.addr + self.offset as u64, size).unwrap_or(&mut []) + }, + _ => &mut [], + } + } + pub fn current_read_slice(&self) -> &[u8] { + match self.current { + Some(d) if !d.is_write() && d.remaining(self.offset) > 0 => { + let size = d.remaining(self.offset); + self.memory.slice(d.addr + self.offset as u64, size).unwrap_or(&[]) + }, + _ => &[], + } } - */ + pub fn w8(&mut self, n: u8) -> io::Result<()> { + self.write_u8(n) + } + + #[allow(unused)] + pub fn w16(&mut self, n: u16) -> io::Result<()> { + self.write_u16::(n) + } + + pub fn w32(&mut self, n: u32) -> io::Result<()> { + self.write_u32::(n) + } + + pub fn w64(&mut self, n: u64) -> io::Result<()> { + self.write_u64::(n) + } + + #[allow(unused)] + pub fn r16(&mut self) -> io::Result { + self.read_u16::() + } + + pub fn r32(&mut self) -> io::Result { + self.read_u32::() + } + + pub fn r64(&mut self) -> io::Result { + self.read_u64::() + } } impl Drop for Chain { diff --git a/rust/src/virtio/vring.rs b/rust/src/virtio/vring.rs index 428ddf4..fb8f016 100644 --- a/rust/src/virtio/vring.rs +++ b/rust/src/virtio/vring.rs @@ -345,7 +345,7 @@ impl Descriptor { self.has_flag(VRING_DESC_F_INDIRECT) } - fn remaining(&self, offset: usize) -> usize { + pub fn remaining(&self, offset: usize) -> usize { if offset >= self.len as usize { 0 } else {