vhost_kern/vdpa: use FAM for vhost_vdpa_config
vhost_vdpa_config has a flexible array member (buf). Let's use vmm_sys_util::fam module to handle it in get_config() and set_config(). This simplifies the code and reduces the unsafe block to just the ioctl call. Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
This commit is contained in:
parent
833b8975cc
commit
64577a3c6c
2 changed files with 34 additions and 37 deletions
|
|
@ -4,22 +4,33 @@
|
|||
//! Kernel-based vhost-vdpa backend.
|
||||
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::os::raw::c_int;
|
||||
use std::io::Error as IOError;
|
||||
use std::os::raw::{c_uchar, c_uint};
|
||||
use std::os::unix::fs::OpenOptionsExt;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
|
||||
use vm_memory::GuestAddressSpace;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
use vmm_sys_util::fam::*;
|
||||
use vmm_sys_util::ioctl::{ioctl_with_mut_ref, ioctl_with_ptr, ioctl_with_ref};
|
||||
|
||||
use std::alloc::{alloc, dealloc, Layout};
|
||||
use std::mem;
|
||||
|
||||
use super::vhost_binding::*;
|
||||
use super::{ioctl_result, Error, Result, VhostKernBackend, VhostKernFeatures};
|
||||
use crate::vdpa::*;
|
||||
use crate::{VhostAccess, VhostIotlbBackend, VhostIotlbMsg, VhostIotlbType};
|
||||
|
||||
// Implement the FamStruct trait for vhost_vdpa_config
|
||||
generate_fam_struct_impl!(
|
||||
vhost_vdpa_config,
|
||||
c_uchar,
|
||||
buf,
|
||||
c_uint,
|
||||
len,
|
||||
c_uint::MAX as usize
|
||||
);
|
||||
|
||||
type VhostVdpaConfig = FamStructWrapper<vhost_vdpa_config>;
|
||||
|
||||
/// Handle for running VHOST_VDPA ioctls.
|
||||
pub struct VhostKernVdpa<AS: GuestAddressSpace> {
|
||||
fd: File,
|
||||
|
|
@ -62,48 +73,33 @@ impl<AS: GuestAddressSpace> VhostVdpa for VhostKernVdpa<AS> {
|
|||
}
|
||||
|
||||
fn get_config(&self, offset: u32, buffer: &mut [u8]) -> Result<()> {
|
||||
let buffer_len = buffer.len();
|
||||
let layout =
|
||||
Layout::from_size_align(mem::size_of::<vhost_vdpa_config>() + buffer_len, 1).unwrap();
|
||||
let ret: c_int;
|
||||
let mut config = VhostVdpaConfig::new(buffer.len())
|
||||
.map_err(|_| Error::IoctlError(IOError::from_raw_os_error(libc::ENOMEM)))?;
|
||||
|
||||
unsafe {
|
||||
let ptr = alloc(layout);
|
||||
let config = ptr as *mut vhost_vdpa_config;
|
||||
(*config).off = offset;
|
||||
(*config).len = buffer_len as u32;
|
||||
config.as_mut_fam_struct().off = offset;
|
||||
|
||||
ret = ioctl_with_ptr(self, VHOST_VDPA_GET_CONFIG(), ptr);
|
||||
|
||||
buffer.copy_from_slice((*config).buf.as_slice(buffer_len));
|
||||
|
||||
dealloc(ptr, layout);
|
||||
let ret = unsafe {
|
||||
ioctl_with_ptr(
|
||||
self,
|
||||
VHOST_VDPA_GET_CONFIG(),
|
||||
config.as_mut_fam_struct_ptr(),
|
||||
)
|
||||
};
|
||||
|
||||
buffer.copy_from_slice(config.as_slice());
|
||||
|
||||
ioctl_result(ret, ())
|
||||
}
|
||||
|
||||
fn set_config(&self, offset: u32, buffer: &[u8]) -> Result<()> {
|
||||
let buffer_len = buffer.len();
|
||||
let layout =
|
||||
Layout::from_size_align(mem::size_of::<vhost_vdpa_config>() + buffer_len, 1).unwrap();
|
||||
let ret: c_int;
|
||||
let mut config = VhostVdpaConfig::new(buffer.len())
|
||||
.map_err(|_| Error::IoctlError(IOError::from_raw_os_error(libc::ENOMEM)))?;
|
||||
|
||||
unsafe {
|
||||
let ptr = alloc(layout);
|
||||
let config = ptr as *mut vhost_vdpa_config;
|
||||
(*config).off = offset;
|
||||
(*config).len = buffer_len as u32;
|
||||
config.as_mut_fam_struct().off = offset;
|
||||
config.as_mut_slice().copy_from_slice(buffer);
|
||||
|
||||
(*config)
|
||||
.buf
|
||||
.as_mut_slice(buffer_len)
|
||||
.copy_from_slice(&buffer);
|
||||
|
||||
ret = ioctl_with_ptr(self, VHOST_VDPA_SET_CONFIG(), ptr);
|
||||
|
||||
dealloc(ptr, layout);
|
||||
};
|
||||
let ret =
|
||||
unsafe { ioctl_with_ptr(self, VHOST_VDPA_SET_CONFIG(), config.as_fam_struct_ptr()) };
|
||||
|
||||
ioctl_result(ret, ())
|
||||
}
|
||||
|
|
@ -199,6 +195,7 @@ impl<AS: GuestAddressSpace> VhostKernFeatures for VhostKernVdpa<AS> {
|
|||
mod tests {
|
||||
const VHOST_VDPA_PATH: &str = "/dev/vhost-vdpa-0";
|
||||
|
||||
use std::alloc::{alloc, dealloc, Layout};
|
||||
use vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap};
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ impl Default for vhost_scsi_target {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct vhost_vdpa_config {
|
||||
pub off: raw::c_uint,
|
||||
pub len: raw::c_uint,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue