From 5fc3f37c9b734682ef7e7e0c4ca41f6b480b7bcf Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 7 Oct 2019 09:03:58 -0700 Subject: [PATCH] vmm: Add iommu=on|off option for --device Having the virtual IOMMU created with --iommu is one thing, but we also need a way to decide if a VFIO device should be attached to the virtual IOMMU or not. That's why we introduce an extra option "iommu" with the value "on" or "off". By default, the device is not attached, which means "iommu=off". Signed-off-by: Sebastien Boeuf --- docs/vfio.md | 2 +- src/main.rs | 4 +++ .../clear/openstack/latest/user_data | 2 +- vmm/src/api/openapi/cloud-hypervisor.yaml | 3 +++ vmm/src/config.rs | 25 +++++++++++++++++-- 5 files changed, 32 insertions(+), 4 deletions(-) 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); }