mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: Support device passthrough with vfio cdev and iommufd
When `--platform iommufd=on` is set, use the vfio cdev interface backed by iommufd instead of the legacy vfio container/group interface for device passthrough. The cdev path opens '/dev/iommu' via IommuFd, allocates an IOAS, and binds VFIO devices through VfioIommufd. The legacy container/group path remains the default and is used when iommufd is not enabled. Add iommufd-ioctls as a workspace dependency and enable the "vfio_cdev" feature on vfio-ioctls for KVM builds. Fixes: #6892 Signed-off-by: Bo Chen <bchen@crusoe.ai>
This commit is contained in:
20
Cargo.lock
generated
20
Cargo.lock
generated
@@ -1097,6 +1097,23 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iommufd-bindings"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd7de3a04f6fd55f171a6682852f7aa360bb848a85e0c610513349e006b3c139"
|
||||
|
||||
[[package]]
|
||||
name = "iommufd-ioctls"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eabd3414d9c4e716c9a198fbfac484625f088c075605372daf037edfe336e18"
|
||||
dependencies = [
|
||||
"iommufd-bindings",
|
||||
"thiserror",
|
||||
"vmm-sys-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnetwork"
|
||||
version = "0.20.0"
|
||||
@@ -2291,6 +2308,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4b1d98dff7f0d219278e406323e7eda4d426447bd203c7828189baf0d8c07b7"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"iommufd-bindings",
|
||||
"iommufd-ioctls",
|
||||
"kvm-bindings",
|
||||
"kvm-ioctls",
|
||||
"libc",
|
||||
@@ -2521,6 +2540,7 @@ dependencies = [
|
||||
"hypervisor",
|
||||
"igvm",
|
||||
"igvm_defs",
|
||||
"iommufd-ioctls",
|
||||
"landlock",
|
||||
"libc",
|
||||
"linux-loader",
|
||||
|
||||
@@ -53,6 +53,7 @@ resolver = "3"
|
||||
[workspace.dependencies]
|
||||
# rust-vmm crates
|
||||
acpi_tables = "0.2.0"
|
||||
iommufd-ioctls = "0.1.0"
|
||||
kvm-bindings = "0.14.0"
|
||||
kvm-ioctls = "0.24.0"
|
||||
linux-loader = "0.13.2"
|
||||
|
||||
@@ -17,8 +17,10 @@ ivshmem = ["devices/ivshmem"]
|
||||
kvm = [
|
||||
"arch/kvm",
|
||||
"hypervisor/kvm",
|
||||
"iommufd-ioctls",
|
||||
"pci/kvm",
|
||||
"vfio-ioctls/kvm",
|
||||
"vfio-ioctls/vfio_cdev",
|
||||
"virtio-devices/kvm",
|
||||
"vm-device/kvm",
|
||||
]
|
||||
@@ -55,6 +57,7 @@ hex = { version = "0.4.3", optional = true }
|
||||
hypervisor = { path = "../hypervisor" }
|
||||
igvm = { workspace = true, optional = true }
|
||||
igvm_defs = { workspace = true, optional = true }
|
||||
iommufd-ioctls = { workspace = true, optional = true }
|
||||
landlock = "0.4.4"
|
||||
libc = { workspace = true }
|
||||
linux-loader = { workspace = true, features = ["bzimage", "elf", "pe"] }
|
||||
|
||||
@@ -76,6 +76,8 @@ use event_monitor::event;
|
||||
use hypervisor::IoEventAddress;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use hypervisor::arch::aarch64::regs::AARCH64_PMU_IRQ;
|
||||
#[cfg(feature = "kvm")]
|
||||
use iommufd_ioctls::IommuFd;
|
||||
use libc::{
|
||||
MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE, TCSANOW, tcsetattr,
|
||||
termios,
|
||||
@@ -90,6 +92,8 @@ use seccompiler::SeccompAction;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use tracer::trace_scoped;
|
||||
#[cfg(feature = "kvm")]
|
||||
use vfio_ioctls::VfioIommufd;
|
||||
use vfio_ioctls::{VfioContainer, VfioDevice, VfioDeviceFd, VfioOps};
|
||||
use virtio_devices::transport::{VirtioPciDevice, VirtioPciDeviceActivator, VirtioTransport};
|
||||
use virtio_devices::vhost_user::VhostUserConfig;
|
||||
@@ -361,6 +365,15 @@ pub enum DeviceManagerError {
|
||||
#[error("Error getting pty peer")]
|
||||
GetPtyPeer(#[source] vmm_sys_util::errno::Error),
|
||||
|
||||
/// Cannot create iommufd
|
||||
#[cfg(feature = "kvm")]
|
||||
#[error("Cannot create iommufd")]
|
||||
IommufdCreate(#[source] iommufd_ioctls::IommufdError),
|
||||
|
||||
/// iommufd is not supported
|
||||
#[error("iommufd is not supported without the kvm feature")]
|
||||
IommufdNotSupported,
|
||||
|
||||
/// Cannot create a VFIO device
|
||||
#[error("Cannot create a VFIO device")]
|
||||
VfioCreate(#[source] vfio_ioctls::VfioError),
|
||||
@@ -3803,9 +3816,31 @@ impl DeviceManager {
|
||||
.try_clone()
|
||||
.map_err(DeviceManagerError::VfioCreate)?;
|
||||
|
||||
Ok(Arc::new(
|
||||
VfioContainer::new(Some(Arc::new(dup))).map_err(DeviceManagerError::VfioCreate)?,
|
||||
))
|
||||
let iommufd = self
|
||||
.config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.platform
|
||||
.as_ref()
|
||||
.is_some_and(|p| p.iommufd);
|
||||
|
||||
if iommufd {
|
||||
#[cfg(feature = "kvm")]
|
||||
{
|
||||
info!("Using vfio cdev mode with iommufd.");
|
||||
let iommufd = IommuFd::new().map_err(DeviceManagerError::IommufdCreate)?;
|
||||
let vfio_iommufd = VfioIommufd::new(Arc::new(iommufd), None, Some(Arc::new(dup)))
|
||||
.map_err(DeviceManagerError::VfioCreate)?;
|
||||
Ok(Arc::new(vfio_iommufd))
|
||||
}
|
||||
#[cfg(not(feature = "kvm"))]
|
||||
Err(DeviceManagerError::IommufdNotSupported)
|
||||
} else {
|
||||
info!("Using vfio legacy mode with vfio container/group.");
|
||||
Ok(Arc::new(
|
||||
VfioContainer::new(Some(Arc::new(dup))).map_err(DeviceManagerError::VfioCreate)?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn add_vfio_device(
|
||||
|
||||
Reference in New Issue
Block a user