Skip to content
This repository has been archived by the owner on Dec 20, 2021. It is now read-only.

Add MSHV support #22

Merged
merged 4 commits into from
Sep 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .buildkite/custom-tests.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"tests": [
{
"test_name": "build-mshv",
"command": "cargo build --release --no-default-features --features mshv",
liuw marked this conversation as resolved.
Show resolved Hide resolved
"platform": ["x86_64"]
},
{
"test_name": "clippy-mshv",
"command": "cargo clippy --workspace --bins --examples --benches --no-default-features --features mshv --all-targets -- -D warnings",
liuw marked this conversation as resolved.
Show resolved Hide resolved
"platform": ["x86_64"]
}
]
}
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ edition = "2018"
[features]
default = ["kvm"]
kvm = ["kvm-ioctls", "kvm-bindings"]
mshv = ["mshv-ioctls", "mshv-bindings"]

[dependencies]
byteorder = ">=1.2.1"
Expand All @@ -19,3 +20,5 @@ kvm-ioctls = { version = "~0", optional = true }
vfio-bindings = "~0"
vm-memory = { version = "0.6", features = ["backend-mmap"] }
vmm-sys-util = "0.8"
mshv-bindings = { git = "https://github.com/rust-vmm/mshv", branch = "main", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", branch = "main", optional = true }
58 changes: 38 additions & 20 deletions src/vfio_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ use kvm_bindings::{
#[cfg(feature = "kvm")]
use kvm_ioctls::DeviceFd;
use log::{debug, error, warn};
#[cfg(all(feature = "mshv", not(feature = "kvm")))]
use mshv_bindings::{
mshv_device_attr, MSHV_DEV_VFIO_GROUP, MSHV_DEV_VFIO_GROUP_ADD, MSHV_DEV_VFIO_GROUP_DEL,
};
#[cfg(all(feature = "mshv", not(feature = "kvm")))]
use mshv_ioctls::DeviceFd;
use vfio_bindings::bindings::vfio::*;
use vm_memory::{Address, GuestMemory, GuestMemoryRegion, MemoryRegionAddress};
use vmm_sys_util::errno::Error as SysError;
Expand All @@ -46,8 +52,7 @@ pub enum VfioError {
UnsetContainer,
ContainerSetIOMMU,
GroupGetDeviceFD,
#[cfg(feature = "kvm")]
KvmSetDeviceAttr(SysError),
SetDeviceAttr(SysError),
VfioDeviceGetInfo,
VfioDeviceGetRegionInfo(SysError),
InvalidPath,
Expand Down Expand Up @@ -87,9 +92,8 @@ impl fmt::Display for VfioError {
"failed to set container's IOMMU driver type as VfioType1V2"
),
VfioError::GroupGetDeviceFD => write!(f, "failed to get vfio device fd"),
#[cfg(feature = "kvm")]
VfioError::KvmSetDeviceAttr(e) => {
write!(f, "failed to set KVM vfio device's attribute: {}", e)
VfioError::SetDeviceAttr(e) => {
write!(f, "failed to set vfio device's attribute: {}", e)
}
VfioError::VfioDeviceGetInfo => {
write!(f, "failed to get vfio device's info or info doesn't match")
Expand Down Expand Up @@ -123,8 +127,7 @@ impl std::error::Error for VfioError {
VfioError::UnsetContainer => None,
VfioError::ContainerSetIOMMU => None,
VfioError::GroupGetDeviceFD => None,
#[cfg(feature = "kvm")]
VfioError::KvmSetDeviceAttr(e) => Some(e),
VfioError::SetDeviceAttr(e) => Some(e),
VfioError::VfioDeviceGetInfo => None,
VfioError::VfioDeviceGetRegionInfo(e) => Some(e),
VfioError::InvalidPath => None,
Expand Down Expand Up @@ -229,34 +232,51 @@ impl VfioContainer {
Ok(())
}

#[cfg(feature = "kvm")]
fn kvm_device_add_group(&self, group_fd: RawFd) -> Result<()> {
let group_fd_ptr = &group_fd as *const i32;
fn device_add_group(&self, group: &VfioGroup) -> Result<()> {
let group_fd_ptr = &group.as_raw_fd() as *const i32;

#[cfg(feature = "kvm")]
let dev_attr = kvm_device_attr {
flags: 0,
group: KVM_DEV_VFIO_GROUP,
attr: u64::from(KVM_DEV_VFIO_GROUP_ADD),
addr: group_fd_ptr as u64,
};

#[cfg(all(feature = "mshv", not(feature = "kvm")))]
let dev_attr = mshv_device_attr {
flags: 0,
group: MSHV_DEV_VFIO_GROUP,
attr: u64::from(MSHV_DEV_VFIO_GROUP_ADD),
addr: group_fd_ptr as u64,
};

self.device_fd
.set_device_attr(&dev_attr)
.map_err(VfioError::KvmSetDeviceAttr)
.map_err(VfioError::SetDeviceAttr)
}

#[cfg(feature = "kvm")]
fn kvm_device_del_group(&self, group_fd: RawFd) -> Result<()> {
let group_fd_ptr = &group_fd as *const i32;
fn device_del_group(&self, group: &VfioGroup) -> Result<()> {
let group_fd_ptr = &group.as_raw_fd() as *const i32;
#[cfg(feature = "kvm")]
let dev_attr = kvm_device_attr {
flags: 0,
group: KVM_DEV_VFIO_GROUP,
attr: u64::from(KVM_DEV_VFIO_GROUP_DEL),
addr: group_fd_ptr as u64,
};

#[cfg(all(feature = "mshv", not(feature = "kvm")))]
let dev_attr = mshv_device_attr {
flags: 0,
group: MSHV_DEV_VFIO_GROUP,
attr: u64::from(MSHV_DEV_VFIO_GROUP_DEL),
addr: group_fd_ptr as u64,
};

self.device_fd
.set_device_attr(&dev_attr)
.map_err(VfioError::KvmSetDeviceAttr)
.map_err(VfioError::SetDeviceAttr)
}

fn get_group(&self, group_id: u32) -> Result<Arc<VfioGroup>> {
Expand Down Expand Up @@ -287,9 +307,8 @@ impl VfioContainer {
}
}

// Add the new group object to the KVM driver.
#[cfg(feature = "kvm")]
if let Err(e) = self.kvm_device_add_group(group.as_raw_fd()) {
// Add the new group object to the hypervisor driver.
if let Err(e) = self.device_add_group(&group) {
let _ =
unsafe { ioctl_with_ref(&*group, VFIO_GROUP_UNSET_CONTAINER(), &self.as_raw_fd()) };
return Err(e);
Expand All @@ -310,8 +329,7 @@ impl VfioContainer {
// - one reference cloned in VfioDevice.drop() and passed into here
// - one reference held by the groups hashmap
if Arc::strong_count(&group) == 3 {
#[cfg(feature = "kvm")]
match self.kvm_device_del_group(group.as_raw_fd()) {
match self.device_del_group(&group) {
Ok(_) => {}
Err(e) => {
error!("Could not delete VFIO group: {:?}", e);
Expand Down