From 751a3020501b83e06af000c71ef28f858197793d Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 16 Jul 2020 10:34:51 +0100 Subject: [PATCH] virtio-devices: Port devices over to new read_config_from_slice() helper Using this helper removes lots of duplicated code across the devices. Signed-off-by: Rob Bradford --- virtio-devices/src/balloon.rs | 18 +++--------------- virtio-devices/src/block.rs | 15 ++------------- virtio-devices/src/console.rs | 16 ++-------------- virtio-devices/src/iommu.rs | 19 ++++--------------- virtio-devices/src/mem.rs | 17 +++-------------- virtio-devices/src/net.rs | 17 +++-------------- virtio-devices/src/pmem.rs | 18 +++--------------- virtio-devices/src/vhost_user/blk.rs | 16 ++-------------- virtio-devices/src/vhost_user/fs.rs | 16 ++-------------- virtio-devices/src/vhost_user/net.rs | 16 ++-------------- 10 files changed, 26 insertions(+), 142 deletions(-) diff --git a/virtio-devices/src/balloon.rs b/virtio-devices/src/balloon.rs index 1264df6a7..ad08ab13d 100644 --- a/virtio-devices/src/balloon.rs +++ b/virtio-devices/src/balloon.rs @@ -20,9 +20,8 @@ use super::{ use crate::vm_memory::GuestMemory; use crate::{VirtioInterrupt, VirtioInterruptType}; use libc::EFD_NONBLOCK; -use std::cmp; use std::fs::File; -use std::io::{self, Write}; +use std::io; use std::mem::size_of; use std::os::unix::io::{AsRawFd, FromRawFd}; use std::result; @@ -471,19 +470,8 @@ impl VirtioDevice for Balloon { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config = self.config.lock().unwrap(); - let config_slice = config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data); } fn activate( diff --git a/virtio-devices/src/block.rs b/virtio-devices/src/block.rs index 620b33ba3..28c13d5fd 100644 --- a/virtio-devices/src/block.rs +++ b/virtio-devices/src/block.rs @@ -17,7 +17,6 @@ use crate::VirtioInterrupt; use anyhow::anyhow; use block_util::{build_disk_image_id, Request, RequestType, VirtioBlockConfig}; use libc::EFD_NONBLOCK; -use std::cmp; use std::collections::HashMap; use std::fs::File; use std::io::{self, Read, Seek, SeekFrom, Write}; @@ -504,18 +503,8 @@ impl VirtioDevice for Block { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config_slice = self.config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.as_slice(), offset, data); } fn write_config(&mut self, offset: u64, data: &[u8]) { diff --git a/virtio-devices/src/console.rs b/virtio-devices/src/console.rs index c86f5f5a5..6dc54e579 100644 --- a/virtio-devices/src/console.rs +++ b/virtio-devices/src/console.rs @@ -505,20 +505,8 @@ impl VirtioDevice for Console { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config = self.config.lock().unwrap(); - let config_slice = config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data); } fn activate( diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index 6df39fbd3..69617e2ad 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -10,11 +10,10 @@ use super::{ use crate::{DmaRemapping, VirtioInterrupt, VirtioInterruptType}; use anyhow::anyhow; use libc::EFD_NONBLOCK; -use std::cmp; use std::collections::BTreeMap; use std::fmt::{self, Display}; use std::fs::File; -use std::io::{self, Write}; +use std::io; use std::mem::size_of; use std::ops::Bound::Included; use std::os::unix::io::{AsRawFd, FromRawFd}; @@ -968,26 +967,16 @@ impl VirtioDevice for Iommu { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { + fn read_config(&self, offset: u64, data: &mut [u8]) { let mut config: Vec = Vec::new(); config.extend_from_slice(self.config.as_slice()); for config_topo_pci_range in self.config_topo_pci_ranges.iter() { config.extend_from_slice(config_topo_pci_range.as_slice()); } - let config_slice = config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + self.read_config_from_slice(config.as_slice(), offset, data); } + fn activate( &mut self, mem: GuestMemoryAtomic, diff --git a/virtio-devices/src/mem.rs b/virtio-devices/src/mem.rs index 5468b0db2..0731e376e 100644 --- a/virtio-devices/src/mem.rs +++ b/virtio-devices/src/mem.rs @@ -21,7 +21,7 @@ use crate::{VirtioInterrupt, VirtioInterruptType}; use libc::EFD_NONBLOCK; use std::cmp; use std::fs::File; -use std::io::{self, Write}; +use std::io; use std::mem::size_of; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::result; @@ -870,19 +870,8 @@ impl VirtioDevice for Mem { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config = self.config.lock().unwrap(); - let config_slice = config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data); } fn activate( diff --git a/virtio-devices/src/net.rs b/virtio-devices/src/net.rs index 223a04b5d..34b1301e3 100644 --- a/virtio-devices/src/net.rs +++ b/virtio-devices/src/net.rs @@ -20,10 +20,9 @@ use net_util::{ open_tap, MacAddr, NetCounters, NetQueuePair, OpenTapError, RxVirtio, Tap, TxVirtio, RX_QUEUE_EVENT, RX_TAP_EVENT, TX_QUEUE_EVENT, }; -use std::cmp; use std::collections::HashMap; use std::fs::File; -use std::io::{self, Write}; +use std::io; use std::net::Ipv4Addr; use std::num::Wrapping; use std::os::unix::io::{AsRawFd, FromRawFd}; @@ -413,18 +412,8 @@ impl VirtioDevice for Net { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config_slice = self.config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.as_slice(), offset, data); } fn activate( diff --git a/virtio-devices/src/pmem.rs b/virtio-devices/src/pmem.rs index 55a8cc7eb..039563086 100644 --- a/virtio-devices/src/pmem.rs +++ b/virtio-devices/src/pmem.rs @@ -15,10 +15,9 @@ use crate::{VirtioInterrupt, VirtioInterruptType}; use anyhow::anyhow; use libc::EFD_NONBLOCK; use serde::ser::{Serialize, SerializeStruct, Serializer}; -use std::cmp; use std::fmt::{self, Display}; use std::fs::File; -use std::io::{self, Write}; +use std::io; use std::mem::size_of; use std::os::unix::io::{AsRawFd, FromRawFd}; use std::result; @@ -463,19 +462,8 @@ impl VirtioDevice for Pmem { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config_slice = self.config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.as_slice(), offset, data); } fn activate( diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index 0285177cb..5be785fcd 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -9,8 +9,6 @@ use super::{Error, Result}; use crate::VirtioInterrupt; use block_util::VirtioBlockConfig; use libc::EFD_NONBLOCK; -use std::cmp; -use std::io::Write; use std::mem; use std::os::unix::io::AsRawFd; use std::result; @@ -188,18 +186,8 @@ impl VirtioDevice for Blk { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config_slice = self.config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.as_slice(), offset, data); } fn write_config(&mut self, offset: u64, data: &[u8]) { diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index b1bb3c72f..a0fef81e6 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -10,9 +10,7 @@ use crate::{ VirtioInterrupt, VirtioSharedMemoryList, VIRTIO_F_VERSION_1, }; use libc::{self, c_void, off64_t, pread64, pwrite64, EFD_NONBLOCK}; -use std::cmp; use std::io; -use std::io::Write; use std::os::unix::io::{AsRawFd, RawFd}; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; @@ -407,18 +405,8 @@ impl VirtioDevice for Fs { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config_slice = self.config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.as_slice(), offset, data); } fn activate( diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index 7489b2c13..5d462a0ad 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -13,8 +13,6 @@ use super::{Error, Result}; use crate::VirtioInterrupt; use libc::EFD_NONBLOCK; use net_util::MacAddr; -use std::cmp; -use std::io::Write; use std::os::unix::io::AsRawFd; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; @@ -194,18 +192,8 @@ impl VirtioDevice for Net { self.acked_features |= v; } - fn read_config(&self, offset: u64, mut data: &mut [u8]) { - let config_slice = self.config.as_slice(); - let config_len = config_slice.len() as u64; - if offset >= config_len { - error!("Failed to read config space"); - return; - } - if let Some(end) = offset.checked_add(data.len() as u64) { - // This write can't fail, offset and end are checked against config_len. - data.write_all(&config_slice[offset as usize..cmp::min(end, config_len) as usize]) - .unwrap(); - } + fn read_config(&self, offset: u64, data: &mut [u8]) { + self.read_config_from_slice(self.config.as_slice(), offset, data); } fn activate(