diff --git a/docs/vfio.md b/docs/vfio.md index f33f44752..fff3a9ff0 100644 --- a/docs/vfio.md +++ b/docs/vfio.md @@ -72,7 +72,7 @@ takes the device's sysfs path as an argument. In our example it is --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \ --cpus 4 \ --memory size=512M \ - --device /sys/bus/pci/devices/0000:01:00.0/ + --device path=/sys/bus/pci/devices/0000:01:00.0/ ``` The guest kernel will then detect the card reader on its PCI bus and provided diff --git a/src/main.rs b/src/main.rs index 908cba60b..8ea37eba8 100755 --- a/src/main.rs +++ b/src/main.rs @@ -198,6 +198,10 @@ fn main() { Arg::with_name("device") .long("device") .help("Direct device assignment parameter") + .help( + "Direct device assignment parameters \ + \"path=,iommu=on|off\"", + ) .takes_value(true) .min_values(1) .group("vm-config"), diff --git a/test_data/cloud-init/clear/openstack/latest/user_data b/test_data/cloud-init/clear/openstack/latest/user_data index 274609405..fc88fae1d 100644 --- a/test_data/cloud-init/clear/openstack/latest/user_data +++ b/test_data/cloud-init/clear/openstack/latest/user_data @@ -51,4 +51,4 @@ write_files: bash -c "echo 0000:00:06.0 > /sys/bus/pci/devices/0000\:00\:06.0/driver/unbind" bash -c "echo 1af4 1041 > /sys/bus/pci/drivers/vfio-pci/new_id" - /mnt/cloud-hypervisor --kernel /mnt/vmlinux --cmdline "console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda2 VFIOTAG" --disk path=/mnt/clear-cloudguest.img path=/mnt/cloudinit.img --cpus 1 --memory size=512M --rng --device /sys/bus/pci/devices/0000:00:06.0/ + /mnt/cloud-hypervisor --kernel /mnt/vmlinux --cmdline "console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda2 VFIOTAG" --disk path=/mnt/clear-cloudguest.img path=/mnt/cloudinit.img --cpus 1 --memory size=512M --rng --device path=/sys/bus/pci/devices/0000:00:06.0/ diff --git a/vmm/src/api/openapi/cloud-hypervisor.yaml b/vmm/src/api/openapi/cloud-hypervisor.yaml index da47c88ad..f985e2073 100644 --- a/vmm/src/api/openapi/cloud-hypervisor.yaml +++ b/vmm/src/api/openapi/cloud-hypervisor.yaml @@ -353,6 +353,9 @@ components: properties: path: type: string + iommu: + type: boolean + default: false VhostUserConfig: required: diff --git a/vmm/src/config.rs b/vmm/src/config.rs index a05933d4a..c8c777556 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -572,12 +572,29 @@ impl ConsoleConfig { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct DeviceConfig { pub path: PathBuf, + #[serde(default)] + pub iommu: bool, } impl DeviceConfig { pub fn parse(device: &str) -> Result { + // Split the parameters based on the comma delimiter + let params_list: Vec<&str> = device.split(',').collect(); + + let mut path_str: &str = ""; + let mut iommu_str: &str = ""; + + for param in params_list.iter() { + if param.starts_with("path=") { + path_str = ¶m[5..]; + } else if param.starts_with("iommu=") { + iommu_str = ¶m[6..]; + } + } + Ok(DeviceConfig { - path: PathBuf::from(device), + path: PathBuf::from(path_str), + iommu: parse_iommu(iommu_str)?, }) } } @@ -843,7 +860,11 @@ impl VmConfig { if let Some(device_list) = &vm_params.devices { let mut device_config_list = Vec::new(); for item in device_list.iter() { - device_config_list.push(DeviceConfig::parse(item)?); + let device_config = DeviceConfig::parse(item)?; + if device_config.iommu { + iommu = true; + } + device_config_list.push(device_config); } devices = Some(device_config_list); }