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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2019-10-02 14:01:36 -07:00 committed by Samuel Ortiz
parent 6e0aa56f06
commit 4b8d7e718d
10 changed files with 297 additions and 249 deletions

View File

@ -113,7 +113,7 @@ $ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor $ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./hypervisor-fw \ --kernel ./hypervisor-fw \
--disk ./clear-29160-kvm.img \ --disk path=clear-29160-kvm.img \
--cpus 4 \ --cpus 4 \
--memory size=1024M \ --memory size=1024M \
--net "tap=,mac=,ip=,mask=" \ --net "tap=,mac=,ip=,mask=" \
@ -167,7 +167,7 @@ $ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor $ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ --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" \ --cmdline "console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \
--cpus 4 \ --cpus 4 \
--memory size=1024M \ --memory size=1024M \
@ -187,7 +187,7 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ --kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--console off \ --console off \
--serial tty \ --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" \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \
--cpus 4 \ --cpus 4 \
--memory size=1024M \ --memory size=1024M \

View File

@ -15,7 +15,7 @@ IMG_VERSION=$(curl https://download.clearlinux.org/latest)
# Get latest clear-kvm image: # Get latest clear-kvm image:
wget -P $HOME/workloads/ https://download.clearlinux.org/current/clear-${IMG_VERSION}-kvm.img.xz wget -P $HOME/workloads/ https://download.clearlinux.org/current/clear-${IMG_VERSION}-kvm.img.xz
# Boot cloud-hypervisor VM with the downloaded image # 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 # Setup connectivity
IFACE=$(ip route | grep default | awk -F 'dev' '{print $2}' | awk -F ' ' '{print $1}') IFACE=$(ip route | grep default | awk -F 'dev' '{print $2}' | awk -F ' ' '{print $1}')
GW=$(ip route | grep vmtap0 | awk -F ' ' '{print $1}') GW=$(ip route | grep vmtap0 | awk -F ' ' '{print $1}')

View File

@ -43,7 +43,7 @@ to easily grep for the tracing logs (e.g.
``` ```
./target/debug/cloud-hypervisor \ ./target/debug/cloud-hypervisor \
--kernel ~/rust-hypervisor-firmware/target/target/release/hypervisor-fw \ --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 \ --cpus 4 \
--memory size=1024M \ --memory size=1024M \
--rng \ --rng \

View File

@ -53,7 +53,7 @@ Assuming you have `clear-kvm.img` and `custom-vmlinux.bin` on your system, here
./cloud-hypervisor \ ./cloud-hypervisor \
--cpus 4 \ --cpus 4 \
--memory "size=512,file=/dev/shm" \ --memory "size=512,file=/dev/shm" \
--disk clear-kvm.img \ --disk path=clear-kvm.img \
--kernel custom-vmlinux.bin \ --kernel custom-vmlinux.bin \
--cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \
--fs tag=virtiofs,sock=/tmp/virtiofs,num_queues=1,queue_size=512 --fs tag=virtiofs,sock=/tmp/virtiofs,num_queues=1,queue_size=512

View File

@ -10,7 +10,7 @@ Use one `--net` command-line argument from cloud-hypervisor to specify the emula
./cloud-hypervisor \ ./cloud-hypervisor \
--cpus 4 \ --cpus 4 \
--memory "size=512M" \ --memory "size=512M" \
--disk my-root-disk.img \ --disk path=my-root-disk.img \
--kernel my-vmlinux.bin \ --kernel my-vmlinux.bin \
--cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \ --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 \ --net tap=ich0,mac=a4:a1:c2:00:00:01,ip=192.168.4.2,mask=255.255.255.0 \

View File

@ -66,7 +66,7 @@ takes the device's sysfs path as an argument. In our example it is
``` ```
./target/debug/cloud-hypervisor \ ./target/debug/cloud-hypervisor \
--kernel ~/vmlinux \ --kernel ~/vmlinux \
--disk ~/clear-29160-kvm.img \ --disk path=~/clear-29160-kvm.img \
--console off \ --console off \
--serial tty \ --serial tty \
--cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \

View File

@ -122,7 +122,10 @@ fn main() {
.arg( .arg(
Arg::with_name("disk") Arg::with_name("disk")
.long("disk") .long("disk")
.help("Path to VM disk image") .help(
"Disk parameters \"path=<disk_image_path>,\
iommu=on|off\"",
)
.takes_value(true) .takes_value(true)
.min_values(1) .min_values(1)
.group("vm-config"), .group("vm-config"),
@ -1015,16 +1018,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&["--serial", "tty", "--console", "off"]) .args(&["--serial", "tty", "--console", "off"])
@ -1065,16 +1068,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.spawn() .spawn()
@ -1103,16 +1106,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.spawn() .spawn()
@ -1141,16 +1144,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.spawn() .spawn()
@ -1182,16 +1185,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.spawn() .spawn()
@ -1235,16 +1238,16 @@ mod tests {
.args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().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"]) .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(&["--kernel", kernel_path.to_str().unwrap()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().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"]) .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(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&[ .args(&[
"--vhost-user-net", "--vhost-user-net",
@ -1423,16 +1426,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&[ .args(&[
@ -1513,11 +1516,11 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&[ .args(&[
@ -1563,16 +1566,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.spawn() .spawn()
@ -1634,16 +1637,16 @@ mod tests {
.args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&[ .args(&[
@ -1759,16 +1762,16 @@ mod tests {
.args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&[ .args(&[
@ -1820,7 +1823,12 @@ mod tests {
.args(&["--cpus", "1"]) .args(&["--cpus", "1"])
.args(&["--memory", "size=512M"]) .args(&["--memory", "size=512M"])
.args(&["--kernel", kernel_path.to_str().unwrap()]) .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(&["--net", guest.default_net_string().as_str()])
.args(&[ .args(&[
"--pmem", "--pmem",
@ -1861,16 +1869,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&[ .args(&[
"--net", "--net",
@ -1914,16 +1922,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&["--serial", "off"]) .args(&["--serial", "off"])
@ -1975,16 +1983,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&["--serial", "null"]) .args(&["--serial", "null"])
@ -2036,16 +2044,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&["--serial", "tty"]) .args(&["--serial", "tty"])
@ -2099,16 +2107,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&[ .args(&[
@ -2162,16 +2170,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&["--console", "tty"]) .args(&["--console", "tty"])
@ -2222,16 +2230,16 @@ mod tests {
.args(&["--kernel", guest.fw_path.as_str()]) .args(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&[ .args(&[
@ -2416,16 +2424,16 @@ mod tests {
.args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().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"]) .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(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&["--serial", "tty", "--console", "off"]) .args(&["--serial", "tty", "--console", "off"])
@ -2549,16 +2557,16 @@ mod tests {
.args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().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"]) .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(&["--kernel", guest.fw_path.as_str()])
.args(&[ .args(&[
"--disk", "--disk",
guest format!(
.disk_config "path={}",
.disk(DiskType::OperatingSystem) guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
.unwrap() )
.as_str(), .as_str(),
guest format!(
.disk_config "path={}",
.disk(DiskType::CloudInit) guest.disk_config.disk(DiskType::CloudInit).unwrap()
.unwrap() )
.as_str(), .as_str(),
]) ])
.args(&["--net", guest.default_net_string().as_str()]) .args(&["--net", guest.default_net_string().as_str()])
.args(&["--vsock", format!("cid=3,sock={}", sock).as_str()]) .args(&["--vsock", format!("cid=3,sock={}", sock).as_str()])

View File

@ -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 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" 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/

View File

@ -225,6 +225,9 @@ components:
properties: properties:
path: path:
type: string type: string
iommu:
type: boolean
default: false
NetConfig: NetConfig:
required: required:

View File

@ -75,6 +75,8 @@ pub enum Error<'a> {
ParseVsockSockParam, ParseVsockSockParam,
/// Missing kernel configuration /// Missing kernel configuration
ValidateMissingKernelConfig, ValidateMissingKernelConfig,
/// Failed parsing iommu parameter for the device.
ParseDeviceIommu,
} }
pub type Result<'a, T> = result::Result<T, Error<'a>>; pub type Result<'a, T> = result::Result<T, Error<'a>>;
@ -114,6 +116,20 @@ fn parse_size(size: &str) -> Result<u64> {
Ok(res << shift) Ok(res << shift)
} }
fn parse_iommu(iommu: &str) -> Result<bool> {
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)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CpusConfig(pub u8); pub struct CpusConfig(pub u8);
@ -210,12 +226,29 @@ impl CmdlineConfig {
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DiskConfig { pub struct DiskConfig {
pub path: PathBuf, pub path: PathBuf,
#[serde(default)]
pub iommu: bool,
} }
impl DiskConfig { impl DiskConfig {
pub fn parse(disk: &str) -> Result<Self> { pub fn parse(disk: &str) -> Result<Self> {
// 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 = &param[5..];
} else if param.starts_with("iommu=") {
iommu_str = &param[6..];
}
}
Ok(DiskConfig { 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<Self> { pub fn parse(vm_params: VmParams) -> Result<Self> {
let iommu = false; let mut iommu = false;
let mut disks: Option<Vec<DiskConfig>> = None; let mut disks: Option<Vec<DiskConfig>> = None;
if let Some(disk_list) = &vm_params.disks { if let Some(disk_list) = &vm_params.disks {
let mut disk_config_list = Vec::new(); let mut disk_config_list = Vec::new();
for item in disk_list.iter() { 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); disks = Some(disk_config_list);
} }