From 4b8d7e718dfb5bb381f701cf2957fe7a47e9aca3 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 2 Oct 2019 14:01:36 -0700 Subject: [PATCH] vmm: Add iommu=on|off option for --disk Having the virtual IOMMU created with --iommu is one thing, but we also need a way to decide if a virtio-blk device should be attached to this 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". One side effect of this new option is that we had to introduce a new option for the disk path, simply called "path=". Signed-off-by: Sebastien Boeuf --- README.md | 6 +- docs/custom-image.md | 2 +- docs/debug-port.md | 2 +- docs/fs.md | 2 +- docs/networking.md | 2 +- docs/vfio.md | 2 +- src/main.rs | 482 +++++++++--------- .../clear/openstack/latest/user_data | 2 +- vmm/src/api/openapi/cloud-hypervisor.yaml | 3 + vmm/src/config.rs | 43 +- 10 files changed, 297 insertions(+), 249 deletions(-) diff --git a/README.md b/README.md index ae1c78543..2301050fd 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ $ pushd $CLOUDH $ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor $ ./cloud-hypervisor/target/release/cloud-hypervisor \ --kernel ./hypervisor-fw \ - --disk ./clear-29160-kvm.img \ + --disk path=clear-29160-kvm.img \ --cpus 4 \ --memory size=1024M \ --net "tap=,mac=,ip=,mask=" \ @@ -167,7 +167,7 @@ $ pushd $CLOUDH $ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor $ ./cloud-hypervisor/target/release/cloud-hypervisor \ --kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ - --disk ./clear-29160-kvm.img \ + --disk path=clear-29160-kvm.img \ --cmdline "console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \ --cpus 4 \ --memory size=1024M \ @@ -187,7 +187,7 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \ --kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ --console off \ --serial tty \ - --disk ./clear-29160-kvm.img \ + --disk path=clear-29160-kvm.img \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \ --cpus 4 \ --memory size=1024M \ diff --git a/docs/custom-image.md b/docs/custom-image.md index fe23d138b..d6cdb27b0 100644 --- a/docs/custom-image.md +++ b/docs/custom-image.md @@ -15,7 +15,7 @@ IMG_VERSION=$(curl https://download.clearlinux.org/latest) # Get latest clear-kvm image: wget -P $HOME/workloads/ https://download.clearlinux.org/current/clear-${IMG_VERSION}-kvm.img.xz # Boot cloud-hypervisor VM with the downloaded image -./cloud-hypervisor -v --kernel $HOME/workloads/vmlinux --disk clear-30970-kvm.img --cmdline "console=ttyS0 console=hvc0 reboot=k panic=1 nomodules root=/dev/vda3" --cpus 1 --memory size=1G --net tap=,mac= +./cloud-hypervisor -v --kernel $HOME/workloads/vmlinux --disk path=clear-30970-kvm.img --cmdline "console=ttyS0 console=hvc0 reboot=k panic=1 nomodules root=/dev/vda3" --cpus 1 --memory size=1G --net tap=,mac= # Setup connectivity IFACE=$(ip route | grep default | awk -F 'dev' '{print $2}' | awk -F ' ' '{print $1}') GW=$(ip route | grep vmtap0 | awk -F ' ' '{print $1}') diff --git a/docs/debug-port.md b/docs/debug-port.md index a8588ac73..e880db06b 100644 --- a/docs/debug-port.md +++ b/docs/debug-port.md @@ -43,7 +43,7 @@ to easily grep for the tracing logs (e.g. ``` ./target/debug/cloud-hypervisor \ --kernel ~/rust-hypervisor-firmware/target/target/release/hypervisor-fw \ - --disk ~/hypervisor/images/clear-30080-kvm.img \ + --disk path=~/hypervisor/images/clear-30080-kvm.img \ --cpus 4 \ --memory size=1024M \ --rng \ diff --git a/docs/fs.md b/docs/fs.md index e4cc87d02..6ca4f181d 100644 --- a/docs/fs.md +++ b/docs/fs.md @@ -53,7 +53,7 @@ Assuming you have `clear-kvm.img` and `custom-vmlinux.bin` on your system, here ./cloud-hypervisor \ --cpus 4 \ --memory "size=512,file=/dev/shm" \ - --disk clear-kvm.img \ + --disk path=clear-kvm.img \ --kernel custom-vmlinux.bin \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \ --fs tag=virtiofs,sock=/tmp/virtiofs,num_queues=1,queue_size=512 diff --git a/docs/networking.md b/docs/networking.md index 293440992..e2fcab531 100644 --- a/docs/networking.md +++ b/docs/networking.md @@ -10,7 +10,7 @@ Use one `--net` command-line argument from cloud-hypervisor to specify the emula ./cloud-hypervisor \ --cpus 4 \ --memory "size=512M" \ - --disk my-root-disk.img \ + --disk path=my-root-disk.img \ --kernel my-vmlinux.bin \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \ --net tap=ich0,mac=a4:a1:c2:00:00:01,ip=192.168.4.2,mask=255.255.255.0 \ diff --git a/docs/vfio.md b/docs/vfio.md index 9ddea9691..f33f44752 100644 --- a/docs/vfio.md +++ b/docs/vfio.md @@ -66,7 +66,7 @@ takes the device's sysfs path as an argument. In our example it is ``` ./target/debug/cloud-hypervisor \ --kernel ~/vmlinux \ - --disk ~/clear-29160-kvm.img \ + --disk path=~/clear-29160-kvm.img \ --console off \ --serial tty \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \ diff --git a/src/main.rs b/src/main.rs index 14dac552a..f81d98aa6 100755 --- a/src/main.rs +++ b/src/main.rs @@ -122,7 +122,10 @@ fn main() { .arg( Arg::with_name("disk") .long("disk") - .help("Path to VM disk image") + .help( + "Disk parameters \"path=,\ + iommu=on|off\"", + ) .takes_value(true) .min_values(1) .group("vm-config"), @@ -1015,16 +1018,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "tty", "--console", "off"]) @@ -1065,16 +1068,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1103,16 +1106,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1141,16 +1144,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1182,16 +1185,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1235,16 +1238,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--cmdline", "root=PARTUUID=19866ecd-ecc4-4ef8-b313-09a92260ef9b console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"]) @@ -1294,16 +1297,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--cmdline", "root=PARTUUID=19866ecd-ecc4-4ef8-b313-09a92260ef9b console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"]) @@ -1361,16 +1364,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&[ "--vhost-user-net", @@ -1423,16 +1426,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -1513,11 +1516,11 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -1563,16 +1566,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1634,16 +1637,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -1759,16 +1762,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -1820,7 +1823,12 @@ mod tests { .args(&["--cpus", "1"]) .args(&["--memory", "size=512M"]) .args(&["--kernel", kernel_path.to_str().unwrap()]) - .args(&["--disk", guest.disk_config.disk(DiskType::CloudInit).unwrap().as_str()]) + .args(&["--disk", + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str()]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ "--pmem", @@ -1861,16 +1869,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&[ "--net", @@ -1914,16 +1922,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "off"]) @@ -1975,16 +1983,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "null"]) @@ -2036,16 +2044,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "tty"]) @@ -2099,16 +2107,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -2162,16 +2170,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--console", "tty"]) @@ -2222,16 +2230,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -2416,16 +2424,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--cmdline", "root=PARTUUID=19866ecd-ecc4-4ef8-b313-09a92260ef9b console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw acpi=off"]) @@ -2478,16 +2486,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "tty", "--console", "off"]) @@ -2549,16 +2557,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--cmdline", "root=PARTUUID=19866ecd-ecc4-4ef8-b313-09a92260ef9b console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"]) @@ -2615,16 +2623,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--vsock", format!("cid=3,sock={}", sock).as_str()]) diff --git a/test_data/cloud-init/clear/openstack/latest/user_data b/test_data/cloud-init/clear/openstack/latest/user_data index ea38d5c4d..6ce86b455 100644 --- a/test_data/cloud-init/clear/openstack/latest/user_data +++ b/test_data/cloud-init/clear/openstack/latest/user_data @@ -53,4 +53,4 @@ write_files: bash -c "echo 0000:00:03.0 > /sys/bus/pci/devices/0000\:00\:03.0/driver/unbind" bash -c "echo 1af4 1041 > /sys/bus/pci/drivers/vfio-pci/new_id" - /mnt/cloud-hypervisor --console off --serial tty --kernel /mnt/vmlinux --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda2 VFIOTAG" --disk /mnt/clear-cloudguest.img /mnt/cloudinit.img --cpus 1 --memory size=512M --rng --device /sys/bus/pci/devices/0000:00:03.0/ + /mnt/cloud-hypervisor --console off --serial tty --kernel /mnt/vmlinux --cmdline "console=ttyS0 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:03.0/ diff --git a/vmm/src/api/openapi/cloud-hypervisor.yaml b/vmm/src/api/openapi/cloud-hypervisor.yaml index b4af1018d..ffb3239c7 100644 --- a/vmm/src/api/openapi/cloud-hypervisor.yaml +++ b/vmm/src/api/openapi/cloud-hypervisor.yaml @@ -225,6 +225,9 @@ components: properties: path: type: string + iommu: + type: boolean + default: false NetConfig: required: diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 119b7cd72..dbb610437 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -75,6 +75,8 @@ pub enum Error<'a> { ParseVsockSockParam, /// Missing kernel configuration ValidateMissingKernelConfig, + /// Failed parsing iommu parameter for the device. + ParseDeviceIommu, } pub type Result<'a, T> = result::Result>; @@ -114,6 +116,20 @@ fn parse_size(size: &str) -> Result { Ok(res << shift) } +fn parse_iommu(iommu: &str) -> Result { + if !iommu.is_empty() { + let res = match iommu { + "on" => true, + "off" => false, + _ => return Err(Error::ParseDeviceIommu), + }; + + Ok(res) + } else { + Ok(false) + } +} + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct CpusConfig(pub u8); @@ -210,12 +226,29 @@ impl CmdlineConfig { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct DiskConfig { pub path: PathBuf, + #[serde(default)] + pub iommu: bool, } impl DiskConfig { pub fn parse(disk: &str) -> Result { + // Split the parameters based on the comma delimiter + let params_list: Vec<&str> = disk.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(DiskConfig { - path: PathBuf::from(disk), + path: PathBuf::from(path_str), + iommu: parse_iommu(iommu_str)?, }) } } @@ -679,13 +712,17 @@ impl VmConfig { } pub fn parse(vm_params: VmParams) -> Result { - let iommu = false; + let mut iommu = false; let mut disks: Option> = None; if let Some(disk_list) = &vm_params.disks { let mut disk_config_list = Vec::new(); for item in disk_list.iter() { - disk_config_list.push(DiskConfig::parse(item)?); + let disk_config = DiskConfig::parse(item)?; + if disk_config.iommu { + iommu = true; + } + disk_config_list.push(disk_config); } disks = Some(disk_config_list); }