summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLiu Jiang <gerry@linux.alibaba.com>2021-02-19 22:07:48 +0800
committerSergio Lopez <slp@sinrega.org>2021-03-01 12:50:56 +0100
commit07eee11be3aa7b82fbbb23a6bf4d933e2fa4ae97 (patch)
treefee36697081e8b18f28dbe8c69c4d77abea8cad6 /src
parent97421f754d8d38508687926b5045c4ed1bd6c107 (diff)
downloadvmm_vhost-07eee11be3aa7b82fbbb23a6bf4d933e2fa4ae97.tar.gz
vhost_kern: add more unit test cases
Add more unit test cases for vhost-kern submodule. Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
Diffstat (limited to 'src')
-rw-r--r--src/vhost_kern/mod.rs48
-rw-r--r--src/vhost_kern/vsock.rs112
2 files changed, 130 insertions, 30 deletions
diff --git a/src/vhost_kern/mod.rs b/src/vhost_kern/mod.rs
index 248cbae..f263a39 100644
--- a/src/vhost_kern/mod.rs
+++ b/src/vhost_kern/mod.rs
@@ -13,7 +13,7 @@
use std::os::unix::io::{AsRawFd, RawFd};
-use vm_memory::GuestAddressSpace;
+use vm_memory::{Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestUsize};
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::ioctl::{ioctl, ioctl_with_mut_ref, ioctl_with_ptr, ioctl_with_ref};
@@ -39,7 +39,7 @@ fn ioctl_result<T>(rc: i32, res: T) -> Result<T> {
/// Represent an in-kernel vhost device backend.
pub trait VhostKernBackend: AsRawFd {
- /// Assoicated type to access guest memory.
+ /// Associated type to access guest memory.
type AS: GuestAddressSpace;
/// Get the object to access the guest's memory.
@@ -55,50 +55,32 @@ pub trait VhostKernBackend: AsRawFd {
return false;
}
- // TODO: the GuestMemory trait lacks of method to look up GPA by HVA,
- // so there's no way to validate HVAs. Please extend vm-memory crate
- // first.
- /*
+ let m = self.mem().memory();
let desc_table_size = 16 * u64::from(queue_size) as GuestUsize;
let avail_ring_size = 6 + 2 * u64::from(queue_size) as GuestUsize;
let used_ring_size = 6 + 8 * u64::from(queue_size) as GuestUsize;
if GuestAddress(config_data.desc_table_addr)
.checked_add(desc_table_size)
- .map_or(true, |v| !self.mem().address_in_range(v))
+ .map_or(true, |v| !m.address_in_range(v))
{
false
} else if GuestAddress(config_data.avail_ring_addr)
.checked_add(avail_ring_size)
- .map_or(true, |v| !self.mem().address_in_range(v))
+ .map_or(true, |v| !m.address_in_range(v))
{
false
} else if GuestAddress(config_data.used_ring_addr)
.checked_add(used_ring_size)
- .map_or(true, |v| !self.mem().address_in_range(v))
+ .map_or(true, |v| !m.address_in_range(v))
{
false
+ } else {
+ config_data.is_log_addr_valid()
}
- */
-
- config_data.is_log_addr_valid()
}
}
impl<T: VhostKernBackend> VhostBackend for T {
- /// Set the current process as the owner of this file descriptor.
- /// This must be run before any other vhost ioctls.
- fn set_owner(&self) -> Result<()> {
- // This ioctl is called on a valid vhost fd and has its return value checked.
- let ret = unsafe { ioctl(self, VHOST_SET_OWNER()) };
- ioctl_result(ret, ())
- }
-
- fn reset_owner(&self) -> Result<()> {
- // This ioctl is called on a valid vhost fd and has its return value checked.
- let ret = unsafe { ioctl(self, VHOST_RESET_OWNER()) };
- ioctl_result(ret, ())
- }
-
/// Get a bitmask of supported virtio/vhost features.
fn get_features(&self) -> Result<u64> {
let mut avail_features: u64 = 0;
@@ -118,6 +100,20 @@ impl<T: VhostKernBackend> VhostBackend for T {
ioctl_result(ret, ())
}
+ /// Set the current process as the owner of this file descriptor.
+ /// This must be run before any other vhost ioctls.
+ fn set_owner(&self) -> Result<()> {
+ // This ioctl is called on a valid vhost fd and has its return value checked.
+ let ret = unsafe { ioctl(self, VHOST_SET_OWNER()) };
+ ioctl_result(ret, ())
+ }
+
+ fn reset_owner(&self) -> Result<()> {
+ // This ioctl is called on a valid vhost fd and has its return value checked.
+ let ret = unsafe { ioctl(self, VHOST_RESET_OWNER()) };
+ ioctl_result(ret, ())
+ }
+
/// Set the guest memory mappings for vhost to use.
fn set_mem_table(&self, regions: &[VhostUserMemoryRegionInfo]) -> Result<()> {
if regions.is_empty() || regions.len() > VHOST_MAX_MEMORY_REGIONS {
diff --git a/src/vhost_kern/vsock.rs b/src/vhost_kern/vsock.rs
index c4149bd..7ccf670 100644
--- a/src/vhost_kern/vsock.rs
+++ b/src/vhost_kern/vsock.rs
@@ -1,22 +1,23 @@
-// Copyright (C) 2019 Alibaba Cloud Computing. All rights reserved.
+// Copyright (C) 2019 Alibaba Cloud. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause
//
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-Google file.
-//! Kernel-based vsock vhost backend.
+//! Kernel-based vhost-vsock backend.
use std::fs::{File, OpenOptions};
use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::{AsRawFd, RawFd};
-use super::vhost_binding::{VHOST_VSOCK_SET_GUEST_CID, VHOST_VSOCK_SET_RUNNING};
-use super::{ioctl_result, Error, Result, VhostKernBackend};
use libc;
use vm_memory::GuestAddressSpace;
use vmm_sys_util::ioctl::ioctl_with_ref;
+use super::vhost_binding::{VHOST_VSOCK_SET_GUEST_CID, VHOST_VSOCK_SET_RUNNING};
+use super::{ioctl_result, Error, Result, VhostKernBackend};
+
const VHOST_PATH: &str = "/dev/vhost-vsock";
/// Handle for running VHOST_VSOCK ioctls.
@@ -79,3 +80,106 @@ impl<AS: GuestAddressSpace> AsRawFd for Vsock<AS> {
self.fd.as_raw_fd()
}
}
+
+#[cfg(test)]
+mod tests {
+ use vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap};
+ use vmm_sys_util::eventfd::EventFd;
+
+ use super::*;
+ use crate::{VhostBackend, VhostUserMemoryRegionInfo, VringConfigData};
+
+ #[test]
+ fn test_vsock_new_device() {
+ let m = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10_0000)]).unwrap();
+ let vsock = Vsock::new(&m).unwrap();
+
+ assert!(vsock.as_raw_fd() >= 0);
+ assert!(vsock.mem().find_region(GuestAddress(0x100)).is_some());
+ assert!(vsock.mem().find_region(GuestAddress(0x10_0000)).is_none());
+ }
+
+ #[test]
+ fn test_vsock_is_valid() {
+ let m = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10_0000)]).unwrap();
+ let vsock = Vsock::new(&m).unwrap();
+
+ let mut config = VringConfigData {
+ queue_max_size: 32,
+ queue_size: 32,
+ flags: 0,
+ desc_table_addr: 0x1000,
+ used_ring_addr: 0x2000,
+ avail_ring_addr: 0x3000,
+ log_addr: None,
+ };
+ assert_eq!(vsock.is_valid(&config), true);
+
+ config.queue_size = 0;
+ assert_eq!(vsock.is_valid(&config), false);
+ config.queue_size = 31;
+ assert_eq!(vsock.is_valid(&config), false);
+ config.queue_size = 33;
+ assert_eq!(vsock.is_valid(&config), false);
+ }
+
+ #[test]
+ fn test_vsock_ioctls() {
+ let m = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10_0000)]).unwrap();
+ let vsock = Vsock::new(&m).unwrap();
+
+ let features = vsock.get_features().unwrap();
+ vsock.set_features(features).unwrap();
+
+ vsock.set_owner().unwrap();
+
+ vsock.set_mem_table(&[]).unwrap_err();
+
+ /*
+ let region = VhostUserMemoryRegionInfo {
+ guest_phys_addr: 0x0,
+ memory_size: 0x10_0000,
+ userspace_addr: 0,
+ mmap_offset: 0,
+ mmap_handle: -1,
+ };
+ vsock.set_mem_table(&[region]).unwrap_err();
+ */
+
+ let region = VhostUserMemoryRegionInfo {
+ guest_phys_addr: 0x0,
+ memory_size: 0x10_0000,
+ userspace_addr: m.get_host_address(GuestAddress(0x0)).unwrap() as u64,
+ mmap_offset: 0,
+ mmap_handle: -1,
+ };
+ vsock.set_mem_table(&[region]).unwrap();
+
+ vsock.set_log_base(0x4000, Some(1)).unwrap_err();
+ vsock.set_log_base(0x4000, None).unwrap();
+
+ let eventfd = EventFd::new(0).unwrap();
+ vsock.set_log_fd(eventfd.as_raw_fd()).unwrap();
+
+ vsock.set_vring_num(0, 32).unwrap();
+
+ let config = VringConfigData {
+ queue_max_size: 32,
+ queue_size: 32,
+ flags: 0,
+ desc_table_addr: 0x1000,
+ used_ring_addr: 0x2000,
+ avail_ring_addr: 0x3000,
+ log_addr: None,
+ };
+ vsock.set_vring_addr(0, &config).unwrap();
+ vsock.set_vring_base(0, 1).unwrap();
+ vsock.set_vring_call(0, &eventfd).unwrap();
+ vsock.set_vring_kick(0, &eventfd).unwrap();
+ vsock.set_vring_err(0, &eventfd).unwrap();
+ assert_eq!(vsock.get_vring_base(0).unwrap(), 1);
+ vsock.set_guest_cid(0xdead).unwrap();
+ //vsock.start().unwrap();
+ //vsock.stop().unwrap();
+ }
+}