From 58010b27310cc27df542294f81a19ea95feded5f Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Fri, 9 Aug 2019 14:25:03 -0700 Subject: devices: virtio: add copy_config() helper function Add a new virtio configuration copying function to replace all of the slightly varying read_config() and write_config() implementations in our virtio devices. This replaces a lot of tricky bounds-checking code with a single central implementation, simplifying the devices to a single call to copy_config() in most cases. The balloon device is also changed to represent its config space as a DataInit struct to match most other devices and remove several unwrap() calls. BUG=None TEST=./build_test TEST=Boot vm_kernel+vm_rootfs in crosvm TEST=Start Crostini on nami Change-Id: Ia49bd6dbe609d17455b9562086bc0b24f327be3f Signed-off-by: Daniel Verkamp Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1749562 Reviewed-by: Dylan Reid Tested-by: kokoro --- devices/src/virtio/input/mod.rs | 53 +++++++++-------------------------------- 1 file changed, 11 insertions(+), 42 deletions(-) (limited to 'devices/src/virtio/input/mod.rs') diff --git a/devices/src/virtio/input/mod.rs b/devices/src/virtio/input/mod.rs index 3bed5ef..29152a2 100644 --- a/devices/src/virtio/input/mod.rs +++ b/devices/src/virtio/input/mod.rs @@ -16,7 +16,7 @@ use data_model::{DataInit, Le16, Le32}; use sys_util::{error, warn, EventFd, GuestAddress, GuestMemory, PollContext, PollToken}; use self::event_source::{input_event, EvdevEventSource, EventSource, SocketEventSource}; -use super::{Queue, VirtioDevice, INTERRUPT_STATUS_USED_RING, TYPE_INPUT}; +use super::{copy_config, Queue, VirtioDevice, INTERRUPT_STATUS_USED_RING, TYPE_INPUT}; use std::collections::BTreeMap; use std::fmt::{self, Display}; use std::io::Read; @@ -233,8 +233,6 @@ pub struct VirtioInputConfig { } impl VirtioInputConfig { - const CONFIG_MEM_SIZE: usize = size_of::(); - fn new( device_ids: virtio_input_device_ids, name: Vec, @@ -266,19 +264,6 @@ impl VirtioInputConfig { )) } - fn validate_read_offsets(&self, offset: usize, len: usize) -> bool { - if offset + len > VirtioInputConfig::CONFIG_MEM_SIZE { - error!( - "Attempt to read from invalid config range: [{}..{}], valid ranges in [0..{}]", - offset, - offset + len, - VirtioInputConfig::CONFIG_MEM_SIZE - ); - return false; - } - true - } - fn build_config_memory(&self) -> virtio_input_config { let mut cfg = virtio_input_config::new(); cfg.select = self.select; @@ -322,35 +307,19 @@ impl VirtioInputConfig { } fn read(&self, offset: usize, data: &mut [u8]) { - let data_len = data.len(); - if self.validate_read_offsets(offset, data_len) { - let config = self.build_config_memory(); - data.clone_from_slice(&config.as_slice()[offset..offset + data_len]); - } - } - - fn validate_write_offsets(&self, offset: usize, len: usize) -> bool { - const MAX_WRITABLE_BYTES: usize = 2; - if offset + len > MAX_WRITABLE_BYTES { - error!( - "Attempt to write to invalid config range: [{}..{}], valid ranges in [0..{}]", - offset, - offset + len, - MAX_WRITABLE_BYTES - ); - return false; - } - true + copy_config( + data, + 0, + self.build_config_memory().as_slice(), + offset as u64, + ); } fn write(&mut self, offset: usize, data: &[u8]) { - let len = data.len(); - if self.validate_write_offsets(offset, len) { - let mut selectors: [u8; 2] = [self.select, self.subsel]; - selectors[offset..offset + len].clone_from_slice(&data); - self.select = selectors[0]; - self.subsel = selectors[1]; - } + let mut config = self.build_config_memory(); + copy_config(config.as_mut_slice(), offset as u64, data, 0); + self.select = config.select; + self.subsel = config.subsel; } } -- cgit 1.4.1