[libvirt PATCH v2 00/22] qemu: Implement virtio-iommu support

The first patch adds QEMU replies and as such has been aggressively snipped to deal with mailing list message size limits. Grab the unabriged version with $ git fetch https://gitlab.com/abologna/libvirt.git virtio-iommu As noted in patch 10, the QEMU feature this series enables has not yet been accepted upstream: the relevant patches are https://lists.gnu.org/archive/html/qemu-devel/2021-10/msg00161.html https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg07819.html and of course this series should only be merged once those have gone in. That said, patches 1-6 are necessary to implement the feature but also not strictly related to it, so they could be merged right away. Changes from [v1]: * rebased after Peter's recent changes enabling JSON for -device. [v1] https://listman.redhat.com/archives/libvir-list/2021-October/msg00459.html Andrea Bolognani (22): tests: Add replies for QEMU 6.2.0 on aarch64 conf: Make virDomainDeviceInfoFormat() const correct qemu: Make qemuBuildDeviceAddressProps() const correct qemu: Make qemuBuildVirtioDevProps() const correct conf: Add IOMMU support to virDomainDeviceDefCopy() conf: Add new/free functions for virDomainIOMMUDef conf: Introduce VIR_PCI_CONNECT_INTEGRATED qemu: Tweak some code qemu: Introduce QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI DONOTMERGEYET: qemu: Introduce QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS conf: Introduce virtio model for <iommu> tests: Add test cases for virtio-iommu qemu: Validate machine type used with virtio-iommu qemu: Validate capabilities for virtio-iommu qemu: Validate use of ACPI with virtio-iommu conf: Add virDomainDeviceInfo to virDomainIOMMUDef qemu: Assign PCI address to virtio-iommu qemu: Validate address type for virtio-iommu tests: Add test for virtio-iommu address qemu: Generate command line for virtio-iommu docs: Document virtio-iommu news: Document virtio-iommu NEWS.rst | 4 + docs/formatdomain.rst | 5 +- docs/schemas/domaincommon.rng | 64 +- src/conf/domain_addr.c | 21 +- src/conf/domain_addr.h | 30 +- src/conf/domain_conf.c | 74 +- src/conf/domain_conf.h | 5 + src/qemu/qemu_capabilities.c | 10 + src/qemu/qemu_capabilities.h | 2 + src/qemu/qemu_command.c | 52 +- src/qemu/qemu_domain_address.c | 33 +- src/qemu/qemu_validate.c | 32 + .../qemu_6.2.0-virt.aarch64.xml | 184 + tests/domaincapsdata/qemu_6.2.0.aarch64.xml | 178 + .../caps_5.0.0.aarch64.replies | 71 +- .../caps_5.0.0.aarch64.xml | 1 + .../caps_5.0.0.ppc64.replies | 59 +- .../qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + .../caps_5.0.0.riscv64.replies | 55 +- .../caps_5.0.0.riscv64.xml | 1 + .../caps_5.0.0.x86_64.replies | 71 +- .../caps_5.0.0.x86_64.xml | 1 + .../caps_5.1.0.x86_64.replies | 71 +- .../caps_5.1.0.x86_64.xml | 1 + .../caps_5.2.0.aarch64.replies | 71 +- .../caps_5.2.0.aarch64.xml | 1 + .../caps_5.2.0.ppc64.replies | 59 +- .../qemucapabilitiesdata/caps_5.2.0.ppc64.xml | 1 + .../caps_5.2.0.riscv64.replies | 55 +- .../caps_5.2.0.riscv64.xml | 1 + .../caps_5.2.0.s390x.replies | 59 +- .../qemucapabilitiesdata/caps_5.2.0.s390x.xml | 1 + .../caps_5.2.0.x86_64.replies | 71 +- .../caps_5.2.0.x86_64.xml | 1 + .../caps_6.0.0.aarch64.replies | 71 +- .../caps_6.0.0.aarch64.xml | 1 + .../caps_6.0.0.s390x.replies | 59 +- .../qemucapabilitiesdata/caps_6.0.0.s390x.xml | 1 + .../caps_6.0.0.x86_64.replies | 71 +- .../caps_6.0.0.x86_64.xml | 1 + .../caps_6.1.0.x86_64.replies | 71 +- .../caps_6.1.0.x86_64.xml | 1 + ...h64.replies => caps_6.2.0.aarch64.replies} | 5594 ++++++++++------- ...0.0.aarch64.xml => caps_6.2.0.aarch64.xml} | 58 +- .../caps_6.2.0.x86_64.replies | 275 +- .../caps_6.2.0.x86_64.xml | 2 + ...fault-cpu-kvm-virt-4.2.aarch64-latest.args | 6 +- ...fault-cpu-tcg-virt-4.2.aarch64-latest.args | 6 +- .../aarch64-tpm.aarch64-latest.args | 2 +- .../aarch64-virt-graphics.aarch64-latest.args | 36 +- .../aarch64-virt-headless.aarch64-latest.args | 28 +- ...ult-video-type-aarch64.aarch64-latest.args | 6 +- .../disk-arm-virtio-sd.aarch64-latest.args | 2 +- ...e-expander-bus-aarch64.aarch64-latest.args | 2 +- ... virtio-iommu-aarch64.aarch64-latest.args} | 17 +- .../qemuxml2argvdata/virtio-iommu-aarch64.xml | 20 + ...mmu-invalid-address-type.x86_64-latest.err | 1 + .../virtio-iommu-invalid-address-type.xml | 20 + ...io-iommu-invalid-address.x86_64-latest.err | 1 + .../virtio-iommu-invalid-address.xml | 20 + .../virtio-iommu-no-acpi.x86_64-latest.err | 1 + .../qemuxml2argvdata/virtio-iommu-no-acpi.xml | 15 + ...rtio-iommu-wrong-machine.x86_64-latest.err | 1 + .../virtio-iommu-wrong-machine.xml | 18 + .../virtio-iommu-x86_64.x86_64-6.1.0.err | 1 + .../virtio-iommu-x86_64.x86_64-latest.args | 31 + .../qemuxml2argvdata/virtio-iommu-x86_64.xml | 18 + tests/qemuxml2argvtest.c | 7 + .../virtio-iommu-aarch64.aarch64-latest.xml | 34 + .../virtio-iommu-x86_64.x86_64-latest.xml | 36 + tests/qemuxml2xmltest.c | 2 + 71 files changed, 5278 insertions(+), 2604 deletions(-) create mode 100644 tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml create mode 100644 tests/domaincapsdata/qemu_6.2.0.aarch64.xml copy tests/qemucapabilitiesdata/{caps_6.0.0.aarch64.replies => caps_6.2.0.aarch64.replies} (92%) copy tests/qemucapabilitiesdata/{caps_6.0.0.aarch64.xml => caps_6.2.0.aarch64.xml} (92%) copy tests/qemuxml2argvdata/{aarch64-default-cpu-tcg-virt-4.2.aarch64-latest.args => virtio-iommu-aarch64.aarch64-latest.args} (54%) create mode 100644 tests/qemuxml2argvdata/virtio-iommu-aarch64.xml create mode 100644 tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.xml create mode 100644 tests/qemuxml2argvdata/virtio-iommu-invalid-address.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-invalid-address.xml create mode 100644 tests/qemuxml2argvdata/virtio-iommu-no-acpi.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-no-acpi.xml create mode 100644 tests/qemuxml2argvdata/virtio-iommu-wrong-machine.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-wrong-machine.xml create mode 100644 tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-6.1.0.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/virtio-iommu-x86_64.xml create mode 100644 tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml -- 2.31.1

These were generated using a QEMU binary built from commit v6.1.0-1552-g362534a643 Notably, this causes the arguments of -device to be generated in JSON format. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- .../qemu_6.2.0-virt.aarch64.xml | 184 + tests/domaincapsdata/qemu_6.2.0.aarch64.xml | 178 + .../caps_6.2.0.aarch64.replies | 28698 ++++++++++++++++ .../caps_6.2.0.aarch64.xml | 538 + ...fault-cpu-kvm-virt-4.2.aarch64-latest.args | 6 +- ...fault-cpu-tcg-virt-4.2.aarch64-latest.args | 6 +- .../aarch64-tpm.aarch64-latest.args | 2 +- .../aarch64-virt-graphics.aarch64-latest.args | 36 +- .../aarch64-virt-headless.aarch64-latest.args | 28 +- ...ult-video-type-aarch64.aarch64-latest.args | 6 +- .../disk-arm-virtio-sd.aarch64-latest.args | 2 +- ...e-expander-bus-aarch64.aarch64-latest.args | 2 +- 12 files changed, 29642 insertions(+), 44 deletions(-) create mode 100644 tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml create mode 100644 tests/domaincapsdata/qemu_6.2.0.aarch64.xml create mode 100644 tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies create mode 100644 tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies new file mode 100644 index 0000000000..e8ce132f3c --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies @@ -0,0 +1,28698 @@ +{ + "execute": "qmp_capabilities", + "id": "libvirt-1" +} + +{ + "return": { + }, + "id": "libvirt-1" +} + +{ + "execute": "query-version", + "id": "libvirt-2" +} + +{ + "return": { + "qemu": { + "micro": 50, + "minor": 1, + "major": 6 + }, + "package": "" + }, + "id": "libvirt-2" +} [...] diff --git a/tests/qemuxml2argvdata/aarch64-default-cpu-kvm-virt-4.2.aarch64-latest.args b/tests/qemuxml2argvdata/aarch64-default-cpu-kvm-virt-4.2.aarch64-latest.args index 9a702f6a16..3b38e779f8 100644 --- a/tests/qemuxml2argvdata/aarch64-default-cpu-kvm-virt-4.2.aarch64-latest.args +++ b/tests/qemuxml2argvdata/aarch64-default-cpu-kvm-virt-4.2.aarch64-latest.args @@ -25,11 +25,11 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \ -no-shutdown \ -no-acpi \ -boot strict=on \ --device pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \ --device pcie-root-port,port=9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \ +-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ -blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/guest.qcow2","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage"}' \ --device virtio-blk-pci,bus=pci.1,addr=0x0,drive=libvirt-1-format,id=virtio-disk0,bootindex=1 \ +-device '{"driver":"virtio-blk-pci","bus":"pci.1","addr":"0x0","drive":"libvirt-1-format","id":"virtio-disk0","bootindex":1}' \ -audiodev id=audio1,driver=none \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/aarch64-default-cpu-tcg-virt-4.2.aarch64-latest.args b/tests/qemuxml2argvdata/aarch64-default-cpu-tcg-virt-4.2.aarch64-latest.args index 7647de0342..d4c2cb03f3 100644 --- a/tests/qemuxml2argvdata/aarch64-default-cpu-tcg-virt-4.2.aarch64-latest.args +++ b/tests/qemuxml2argvdata/aarch64-default-cpu-tcg-virt-4.2.aarch64-latest.args @@ -26,11 +26,11 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \ -no-shutdown \ -no-acpi \ -boot strict=on \ --device pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \ --device pcie-root-port,port=9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \ +-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ -blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/guest.qcow2","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage"}' \ --device virtio-blk-pci,bus=pci.1,addr=0x0,drive=libvirt-1-format,id=virtio-disk0,bootindex=1 \ +-device '{"driver":"virtio-blk-pci","bus":"pci.1","addr":"0x0","drive":"libvirt-1-format","id":"virtio-disk0","bootindex":1}' \ -audiodev id=audio1,driver=none \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/aarch64-tpm.aarch64-latest.args b/tests/qemuxml2argvdata/aarch64-tpm.aarch64-latest.args index 67401b8cf4..1ea17a32f7 100644 --- a/tests/qemuxml2argvdata/aarch64-tpm.aarch64-latest.args +++ b/tests/qemuxml2argvdata/aarch64-tpm.aarch64-latest.args @@ -28,7 +28,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-aarch64test/.config \ -boot strict=on \ -tpmdev emulator,id=tpm-tpm0,chardev=chrtpm \ -chardev socket,id=chrtpm,path=/dev/test \ --device tpm-tis-device,tpmdev=tpm-tpm0,id=tpm0 \ +-device '{"driver":"tpm-tis-device","tpmdev":"tpm-tpm0","id":"tpm0"}' \ -audiodev id=audio1,driver=none \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args b/tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args index 878deacf76..3c8ebf3155 100644 --- a/tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args +++ b/tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args @@ -28,32 +28,32 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ --device pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \ --device pcie-root-port,port=9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ --device pcie-root-port,port=10,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \ --device pcie-root-port,port=11,chassis=4,id=pci.4,bus=pcie.0,addr=0x1.0x3 \ --device pcie-root-port,port=12,chassis=5,id=pci.5,bus=pcie.0,addr=0x1.0x4 \ --device pcie-root-port,port=13,chassis=6,id=pci.6,bus=pcie.0,addr=0x1.0x5 \ --device pcie-root-port,port=14,chassis=7,id=pci.7,bus=pcie.0,addr=0x1.0x6 \ --device pcie-root-port,port=15,chassis=8,id=pci.8,bus=pcie.0,addr=0x1.0x7 \ --device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 \ --device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \ +-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \ +-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ +-device '{"driver":"pcie-root-port","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}' \ +-device '{"driver":"pcie-root-port","port":11,"chassis":4,"id":"pci.4","bus":"pcie.0","addr":"0x1.0x3"}' \ +-device '{"driver":"pcie-root-port","port":12,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x1.0x4"}' \ +-device '{"driver":"pcie-root-port","port":13,"chassis":6,"id":"pci.6","bus":"pcie.0","addr":"0x1.0x5"}' \ +-device '{"driver":"pcie-root-port","port":14,"chassis":7,"id":"pci.7","bus":"pcie.0","addr":"0x1.0x6"}' \ +-device '{"driver":"pcie-root-port","port":15,"chassis":8,"id":"pci.8","bus":"pcie.0","addr":"0x1.0x7"}' \ +-device '{"driver":"qemu-xhci","p2":15,"p3":15,"id":"usb","bus":"pci.2","addr":"0x0"}' \ +-device '{"driver":"virtio-serial-pci","id":"virtio-serial0","bus":"pci.3","addr":"0x0"}' \ -blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/guest.qcow2","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage"}' \ --device virtio-blk-pci,bus=pci.4,addr=0x0,drive=libvirt-1-format,id=virtio-disk0,bootindex=1 \ +-device '{"driver":"virtio-blk-pci","bus":"pci.4","addr":"0x0","drive":"libvirt-1-format","id":"virtio-disk0","bootindex":1}' \ -netdev user,id=hostnet0 \ --device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:53:45:a5,bus=pci.1,addr=0x0 \ +-device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:53:45:a5","bus":"pci.1","addr":"0x0"}' \ -chardev pty,id=charserial0 \ -serial chardev:charserial0 \ -chardev socket,id=charchannel0,fd=1729,server=on,wait=off \ --device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 \ --device usb-tablet,id=input0,bus=usb.0,port=1 \ --device usb-kbd,id=input1,bus=usb.0,port=2 \ +-device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":1,"chardev":"charchannel0","id":"channel0","name":"org.qemu.guest_agent.0"}' \ +-device '{"driver":"usb-tablet","id":"input0","bus":"usb.0","port":"1"}' \ +-device '{"driver":"usb-kbd","id":"input1","bus":"usb.0","port":"2"}' \ -audiodev id=audio1,driver=none \ -vnc 127.0.0.1:0,audiodev=audio1 \ --device virtio-gpu-pci,id=video0,max_outputs=1,bus=pci.7,addr=0x0 \ --device virtio-balloon-pci,id=balloon0,bus=pci.5,addr=0x0 \ +-device '{"driver":"virtio-gpu-pci","id":"video0","max_outputs":1,"bus":"pci.7","addr":"0x0"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.5","addr":"0x0"}' \ -object '{"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"}' \ --device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.6,addr=0x0 \ +-device '{"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.6","addr":"0x0"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/aarch64-virt-headless.aarch64-latest.args b/tests/qemuxml2argvdata/aarch64-virt-headless.aarch64-latest.args index 71838bc407..b8052fa967 100644 --- a/tests/qemuxml2argvdata/aarch64-virt-headless.aarch64-latest.args +++ b/tests/qemuxml2argvdata/aarch64-virt-headless.aarch64-latest.args @@ -29,27 +29,27 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ --device pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \ --device pcie-root-port,port=9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ --device pcie-root-port,port=10,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \ --device pcie-root-port,port=11,chassis=4,id=pci.4,bus=pcie.0,addr=0x1.0x3 \ --device pcie-root-port,port=12,chassis=5,id=pci.5,bus=pcie.0,addr=0x1.0x4 \ --device pcie-root-port,port=13,chassis=6,id=pci.6,bus=pcie.0,addr=0x1.0x5 \ --device pcie-root-port,port=14,chassis=7,id=pci.7,bus=pcie.0,addr=0x1.0x6 \ --device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 \ --device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \ +-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \ +-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ +-device '{"driver":"pcie-root-port","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}' \ +-device '{"driver":"pcie-root-port","port":11,"chassis":4,"id":"pci.4","bus":"pcie.0","addr":"0x1.0x3"}' \ +-device '{"driver":"pcie-root-port","port":12,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x1.0x4"}' \ +-device '{"driver":"pcie-root-port","port":13,"chassis":6,"id":"pci.6","bus":"pcie.0","addr":"0x1.0x5"}' \ +-device '{"driver":"pcie-root-port","port":14,"chassis":7,"id":"pci.7","bus":"pcie.0","addr":"0x1.0x6"}' \ +-device '{"driver":"qemu-xhci","p2":15,"p3":15,"id":"usb","bus":"pci.2","addr":"0x0"}' \ +-device '{"driver":"virtio-serial-pci","id":"virtio-serial0","bus":"pci.3","addr":"0x0"}' \ -blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/guest.qcow2","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage"}' \ --device virtio-blk-pci,bus=pci.4,addr=0x0,drive=libvirt-1-format,id=virtio-disk0,bootindex=1 \ +-device '{"driver":"virtio-blk-pci","bus":"pci.4","addr":"0x0","drive":"libvirt-1-format","id":"virtio-disk0","bootindex":1}' \ -netdev user,id=hostnet0 \ --device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:09:a4:37,bus=pci.1,addr=0x0 \ +-device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:09:a4:37","bus":"pci.1","addr":"0x0"}' \ -chardev pty,id=charserial0 \ -serial chardev:charserial0 \ -chardev socket,id=charchannel0,fd=1729,server=on,wait=off \ --device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 \ +-device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":1,"chardev":"charchannel0","id":"channel0","name":"org.qemu.guest_agent.0"}' \ -audiodev id=audio1,driver=none \ --device virtio-balloon-pci,id=balloon0,bus=pci.5,addr=0x0 \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.5","addr":"0x0"}' \ -object '{"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"}' \ --device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.6,addr=0x0 \ +-device '{"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.6","addr":"0x0"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/default-video-type-aarch64.aarch64-latest.args b/tests/qemuxml2argvdata/default-video-type-aarch64.aarch64-latest.args index 5b7f77e348..7d5655e966 100644 --- a/tests/qemuxml2argvdata/default-video-type-aarch64.aarch64-latest.args +++ b/tests/qemuxml2argvdata/default-video-type-aarch64.aarch64-latest.args @@ -24,10 +24,10 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-default-video-type-a/.config \ -no-shutdown \ -no-acpi \ -boot strict=on \ --device pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \ --device pcie-root-port,port=9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \ +-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ -audiodev id=audio1,driver=none \ -vnc 127.0.0.1:0,audiodev=audio1 \ --device virtio-gpu-pci,id=video0,max_outputs=1,bus=pci.1,addr=0x0 \ +-device '{"driver":"virtio-gpu-pci","id":"video0","max_outputs":1,"bus":"pci.1","addr":"0x0"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/disk-arm-virtio-sd.aarch64-latest.args b/tests/qemuxml2argvdata/disk-arm-virtio-sd.aarch64-latest.args index 16d6ba2fc9..3bf3da3c26 100644 --- a/tests/qemuxml2argvdata/disk-arm-virtio-sd.aarch64-latest.args +++ b/tests/qemuxml2argvdata/disk-arm-virtio-sd.aarch64-latest.args @@ -33,7 +33,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-armtest/.config \ -drive file=/arm-sd.qcow2,format=qcow2,if=sd,index=0 \ -blockdev '{"driver":"file","filename":"/arm-virtio.qcow2","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage"}' \ --device virtio-blk-device,drive=libvirt-1-format,id=virtio-disk0 \ +-device '{"driver":"virtio-blk-device","drive":"libvirt-1-format","id":"virtio-disk0"}' \ -audiodev id=audio1,driver=none \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/pcie-expander-bus-aarch64.aarch64-latest.args b/tests/qemuxml2argvdata/pcie-expander-bus-aarch64.aarch64-latest.args index d3b7f724aa..fe027f4e63 100644 --- a/tests/qemuxml2argvdata/pcie-expander-bus-aarch64.aarch64-latest.args +++ b/tests/qemuxml2argvdata/pcie-expander-bus-aarch64.aarch64-latest.args @@ -26,7 +26,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-pcie-expander-bus-te/.config \ -no-shutdown \ -no-acpi \ -boot strict=on \ --device pxb-pcie,bus_nr=254,id=pci.1,bus=pcie.0,addr=0x1 \ +-device '{"driver":"pxb-pcie","bus_nr":254,"id":"pci.1","bus":"pcie.0","addr":"0x1"}' \ -audiodev id=audio1,driver=none \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on -- 2.31.1

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/domain_addr.c | 4 ++-- src/conf/domain_addr.h | 4 ++-- src/conf/domain_conf.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 53b39923e8..fe6520cf3a 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1829,7 +1829,7 @@ virDomainVirtioSerialAddrIsComplete(virDomainDeviceInfo *info) bool -virDomainUSBAddressPortIsValid(unsigned int *port) +virDomainUSBAddressPortIsValid(const unsigned int *port) { return port[0] != 0; } @@ -1837,7 +1837,7 @@ virDomainUSBAddressPortIsValid(unsigned int *port) void virDomainUSBAddressPortFormatBuf(virBuffer *buf, - unsigned int *port) + const unsigned int *port) { size_t i; diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 3f8fcf8acb..814b556024 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -246,12 +246,12 @@ virDomainVirtioSerialAddrAutoAssign(virDomainDef *def, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); bool -virDomainUSBAddressPortIsValid(unsigned int *port) +virDomainUSBAddressPortIsValid(const unsigned int *port) ATTRIBUTE_NONNULL(1); void virDomainUSBAddressPortFormatBuf(virBuffer *buf, - unsigned int *port) + const unsigned int *port) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); #define VIR_DOMAIN_USB_HUB_PORTS 8 diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6fcf86ba58..a3f0a27058 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6334,7 +6334,7 @@ virDomainVirtioOptionsFormat(virBuffer *buf, static void ATTRIBUTE_NONNULL(2) virDomainDeviceInfoFormat(virBuffer *buf, - virDomainDeviceInfo *info, + const virDomainDeviceInfo *info, unsigned int flags) { g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; -- 2.31.1

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1084f5acc7..035943fa96 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -359,7 +359,7 @@ qemuVirCommandGetDevSet(virCommand *cmd, int fd) static char * qemuBuildDeviceAddressPCIGetBus(const virDomainDef *domainDef, - virDomainDeviceInfo *info) + const virDomainDeviceInfo *info) { g_autofree char *devStr = NULL; const char *contAlias = NULL; @@ -427,7 +427,7 @@ qemuBuildDeviceAddressPCIGetBus(const virDomainDef *domainDef, static int qemuBuildDeviceAddresDriveProps(virJSONValue *props, const virDomainDef *domainDef, - virDomainDeviceInfo *info) + const virDomainDeviceInfo *info) { g_autofree char *bus = NULL; virDomainControllerDef *controller = NULL; @@ -563,7 +563,7 @@ qemuBuildDeviceAddresDriveProps(virJSONValue *props, static int qemuBuildDeviceAddressProps(virJSONValue *props, const virDomainDef *domainDef, - virDomainDeviceInfo *info) + const virDomainDeviceInfo *info) { switch ((virDomainDeviceAddressType) info->type) { case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: { -- 2.31.1

This involves a bit of a hack, but is overall preferable to forcing callers to pass non-const devdata as argument. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 035943fa96..d6df50ec73 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -812,7 +812,7 @@ qemuDeviceVideoGetModel(virQEMUCaps *qemuCaps, static void -qemuBuildVirtioDevGetConfigDev(virDomainDeviceDef *device, +qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device, virQEMUCaps *qemuCaps, const char **baseName, virDomainVirtioOptions **virtioOptions, @@ -976,7 +976,7 @@ qemuBuildVirtioDevGetConfigDev(virDomainDeviceDef *device, static int -qemuBuildVirtioDevGetConfig(virDomainDeviceDef *device, +qemuBuildVirtioDevGetConfig(const virDomainDeviceDef *device, virQEMUCaps *qemuCaps, char **devtype, virDomainVirtioOptions **virtioOptions, @@ -1094,17 +1094,21 @@ qemuBuildVirtioDevGetConfig(virDomainDeviceDef *device, */ static virJSONValue * qemuBuildVirtioDevProps(virDomainDeviceType devtype, - void *devdata, + const void *devdata, virQEMUCaps *qemuCaps) { g_autoptr(virJSONValue) props = NULL; - virDomainDeviceDef device = { .type = devtype }; + const virDomainDeviceDef device = { .type = devtype }; g_autofree char *model = NULL; virTristateSwitch disableLegacy = VIR_TRISTATE_SWITCH_ABSENT; virTristateSwitch disableModern = VIR_TRISTATE_SWITCH_ABSENT; virDomainVirtioOptions *virtioOptions = NULL; - virDomainDeviceSetData(&device, devdata); + /* We temporarily cast the const away here, but that's safe to do + * because the called function simply sets the correct member of + * device to devdata based on devtype. Futher uses of device will + * not touch its contents */ + virDomainDeviceSetData((virDomainDeviceDef *) &device, (void *) devdata); if (qemuBuildVirtioDevGetConfig(&device, qemuCaps, &model, &virtioOptions, &disableLegacy, &disableModern) < 0) -- 2.31.1

There doesn't seem to be a reason for IOMMUs not to be handled by this function. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/domain_conf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a3f0a27058..0618343b79 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -29708,6 +29708,10 @@ virDomainDeviceDefCopy(virDomainDeviceDef *src, virDomainShmemDefFormat(&buf, src->data.shmem, flags); rc = 0; break; + case VIR_DOMAIN_DEVICE_IOMMU: + virDomainIOMMUDefFormat(&buf, src->data.iommu); + rc = 0; + break; case VIR_DOMAIN_DEVICE_VSOCK: virDomainVsockDefFormat(&buf, src->data.vsock); rc = 0; @@ -29720,7 +29724,6 @@ virDomainDeviceDefCopy(virDomainDeviceDef *src, case VIR_DOMAIN_DEVICE_SMARTCARD: case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: - case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_INTERNAL_ERROR, _("Copying definition of '%d' type " -- 2.31.1

This will make it possible to limit changes to a single spot later on, and is also just an overall nicer way to create and destroy objects. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/domain_conf.c | 29 +++++++++++++++++++++++++---- src/conf/domain_conf.h | 3 +++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0618343b79..15228d1e38 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2534,6 +2534,27 @@ virDomainVsockDefFree(virDomainVsockDef *vsock) } +virDomainIOMMUDef * +virDomainIOMMUDefNew(void) +{ + g_autoptr(virDomainIOMMUDef) iommu = NULL; + + iommu = g_new0(virDomainIOMMUDef, 1); + + return g_steal_pointer(&iommu); +} + + +void +virDomainIOMMUDefFree(virDomainIOMMUDef *iommu) +{ + if (!iommu) + return; + + g_free(iommu); +} + + void virDomainNetTeamingInfoFree(virDomainNetTeamingInfo *teaming) { @@ -3336,7 +3357,7 @@ void virDomainDeviceDefFree(virDomainDeviceDef *def) virDomainMemoryDefFree(def->data.memory); break; case VIR_DOMAIN_DEVICE_IOMMU: - g_free(def->data.iommu); + virDomainIOMMUDefFree(def->data.iommu); break; case VIR_DOMAIN_DEVICE_VSOCK: virDomainVsockDefFree(def->data.vsock); @@ -3674,7 +3695,7 @@ void virDomainDefFree(virDomainDef *def) virDomainPanicDefFree(def->panics[i]); g_free(def->panics); - g_free(def->iommu); + virDomainIOMMUDefFree(def->iommu); g_free(def->idmap.uidmap); g_free(def->idmap.gidmap); @@ -14923,11 +14944,11 @@ virDomainIOMMUDefParseXML(xmlNodePtr node, { VIR_XPATH_NODE_AUTORESTORE(ctxt) xmlNodePtr driver; - g_autofree virDomainIOMMUDef *iommu = NULL; + g_autoptr(virDomainIOMMUDef) iommu = NULL; ctxt->node = node; - iommu = g_new0(virDomainIOMMUDef, 1); + iommu = virDomainIOMMUDefNew(); if (virXMLPropEnum(node, "model", virDomainIOMMUModelTypeFromString, VIR_XML_PROP_REQUIRED, &iommu->model) < 0) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1ac802feca..4624bad1f7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3300,6 +3300,9 @@ bool virDomainControllerIsPSeriesPHB(const virDomainControllerDef *cont); virDomainFSDef *virDomainFSDefNew(virDomainXMLOption *xmlopt); void virDomainFSDefFree(virDomainFSDef *def); void virDomainActualNetDefFree(virDomainActualNetDef *def); +virDomainIOMMUDef *virDomainIOMMUDefNew(void); +void virDomainIOMMUDefFree(virDomainIOMMUDef *iommu); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainIOMMUDef, virDomainIOMMUDefFree); virDomainVsockDef *virDomainVsockDefNew(virDomainXMLOption *xmlopt); void virDomainVsockDefFree(virDomainVsockDef *vsock); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVsockDef, virDomainVsockDefFree); -- 2.31.1

This new flag can be used to convince the PCI address assignment algorithm to place a device directly on the root bus. It will be used to implement support for virtio-iommu, which needs to be an integrated device in order to work correctly. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/domain_addr.c | 17 +++++++++++++++++ src/conf/domain_addr.h | 26 +++++++++++++++----------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index fe6520cf3a..035d60460f 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -303,6 +303,23 @@ virDomainPCIAddressFlagsCompatible(virPCIDeviceAddress *addr, virErrorNumber errType = (fromConfig ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR); + if (devFlags & VIR_PCI_CONNECT_INTEGRATED) { + if (addr->bus == 0) { + /* pcie-root doesn't usually allow endpoint devices to be + * plugged directly into it, but for integrated devices + * that's exactly what we want */ + busFlags |= VIR_PCI_CONNECT_AUTOASSIGN; + } else { + if (reportError) { + virReportError(errType, + _("The device at PCI address %s needs to be " + "an integrated device (bus=0)"), + addrStr); + } + return false; + } + } + if (fromConfig) { /* If the requested connection was manually specified in * config, allow a PCI device to connect to a PCIe slot, or diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 814b556024..1772ea7088 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -35,24 +35,28 @@ typedef enum { VIR_PCI_CONNECT_AUTOASSIGN = 1 << 0, /* okay to autoassign a device to this controller */ VIR_PCI_CONNECT_HOTPLUGGABLE = 1 << 1, /* is hotplug needed/supported */ + /* Set for devices that can only work as integrated devices (directly + * connected to pci.0 or pcie.0, with no additional buses in between) */ + VIR_PCI_CONNECT_INTEGRATED = 1 << 2, + /* set for devices that can share a single slot in auto-assignment * (by assigning one device to each of the 8 functions on the slot) */ - VIR_PCI_CONNECT_AGGREGATE_SLOT = 1 << 2, + VIR_PCI_CONNECT_AGGREGATE_SLOT = 1 << 3, /* kinds of devices as a bitmap so they can be combined (some PCI * controllers permit connecting multiple types of devices) */ - VIR_PCI_CONNECT_TYPE_PCI_DEVICE = 1 << 3, - VIR_PCI_CONNECT_TYPE_PCIE_DEVICE = 1 << 4, - VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT = 1 << 5, - VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT = 1 << 6, - VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT = 1 << 7, - VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE = 1 << 8, - VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS = 1 << 9, - VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS = 1 << 10, - VIR_PCI_CONNECT_TYPE_PCI_BRIDGE = 1 << 11, - VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE = 1 << 12, + VIR_PCI_CONNECT_TYPE_PCI_DEVICE = 1 << 4, + VIR_PCI_CONNECT_TYPE_PCIE_DEVICE = 1 << 5, + VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT = 1 << 6, + VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT = 1 << 7, + VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT = 1 << 8, + VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE = 1 << 9, + VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS = 1 << 10, + VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS = 1 << 11, + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE = 1 << 12, + VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE = 1 << 13, } virDomainPCIConnectFlags; /* a combination of all bits that describe the type of connections -- 2.31.1

The altered code is functionally equivalent to the previous one, but it's already laid down in a way that will make further changes easier and less messy. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 18 +++++++++--------- src/qemu/qemu_domain_address.c | 23 ++++++++++++++++++++++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d6df50ec73..74e5bac7a2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -952,6 +952,9 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device, } break; + case VIR_DOMAIN_DEVICE_IOMMU: + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_WATCHDOG: @@ -966,7 +969,6 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_MEMORY: - case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_LAST: default: @@ -6540,14 +6542,13 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, virQEMUCaps *qemuCaps) { const virDomainIOMMUDef *iommu = def->iommu; + g_autoptr(virJSONValue) props = NULL; if (!iommu) return 0; switch (iommu->model) { - case VIR_DOMAIN_IOMMU_MODEL_INTEL: { - g_autoptr(virJSONValue) props = NULL; - + case VIR_DOMAIN_IOMMU_MODEL_INTEL: if (virJSONValueObjectCreate(&props, "s:driver", "intel-iommu", "S:intremap", qemuOnOffAuto(iommu->intremap), @@ -6562,7 +6563,6 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, return -1; return 0; - } case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: /* There is no -device for SMMUv3, so nothing to be done here */ @@ -7154,14 +7154,14 @@ qemuBuildMachineCommandLine(virCommand *cmd, if (def->iommu) { switch (def->iommu->model) { - case VIR_DOMAIN_IOMMU_MODEL_INTEL: - /* The 'intel' IOMMu is formatted in qemuBuildIOMMUCommandLine */ - break; - case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: virBufferAddLit(&buf, ",iommu=smmuv3"); break; + case VIR_DOMAIN_IOMMU_MODEL_INTEL: + /* These IOMMUs are formatted in qemuBuildIOMMUCommandLine */ + break; + case VIR_DOMAIN_IOMMU_MODEL_LAST: default: virReportEnumRangeError(virDomainIOMMUModel, def->iommu->model); diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index c43ad23cf5..733fa35444 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1001,6 +1001,16 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, } break; + case VIR_DOMAIN_DEVICE_IOMMU: + switch ((virDomainIOMMUModel) dev->data.iommu->model) { + case VIR_DOMAIN_IOMMU_MODEL_INTEL: + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + case VIR_DOMAIN_IOMMU_MODEL_LAST: + /* These are not PCI devices */ + return 0; + } + break; + case VIR_DOMAIN_DEVICE_VSOCK: switch ((virDomainVsockModel) dev->data.vsock->model) { case VIR_DOMAIN_VSOCK_MODEL_VIRTIO_TRANSITIONAL: @@ -1040,7 +1050,6 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, /* These devices don't even have a DeviceInfo */ case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_GRAPHICS: - case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_LAST: case VIR_DOMAIN_DEVICE_NONE: @@ -2369,6 +2378,18 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, /* Nada - none are PCI based (yet) */ } + if (def->iommu) { + virDomainIOMMUDef *iommu = def->iommu; + + switch ((virDomainIOMMUModel) iommu->model) { + case VIR_DOMAIN_IOMMU_MODEL_INTEL: + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + case VIR_DOMAIN_IOMMU_MODEL_LAST: + /* These are not PCI devices */ + break; + } + } + if (def->vsock && virDeviceInfoPCIAddressIsWanted(&def->vsock->info)) { -- 2.31.1

This capability detects the availability of the virtio-iommu-pci device. Note that, while this device is present even in somewhat old versions of QEMU, it's only some recent changes that made it actually usable for our purposes. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.riscv64.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml | 1 + 18 files changed, 19 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index cddd39924d..30eed6b1b9 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -651,6 +651,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "chardev.json", /* QEMU_CAPS_CHARDEV_JSON */ "device.json", /* QEMU_CAPS_DEVICE_JSON */ "query-dirty-rate", /* QEMU_CAPS_QUERY_DIRTY_RATE */ + "virtio-iommu-pci", /* QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI */ ); @@ -1367,6 +1368,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "virtio-vga-gl", QEMU_CAPS_VIRTIO_VGA_GL }, { "s390-pv-guest", QEMU_CAPS_S390_PV_GUEST }, { "virtio-mem-pci", QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI }, + { "virtio-iommu-pci", QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI }, }; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index bb53d9ae46..d8417c1955 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -631,6 +631,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_CHARDEV_JSON, /* -chardev accepts JSON */ QEMU_CAPS_DEVICE_JSON, /* -device accepts JSON */ QEMU_CAPS_QUERY_DIRTY_RATE, /* accepts query-dirty-rate */ + QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI, /* -device virtio-iommu-pci */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml index bb6a7d5ee7..bb985a3432 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml @@ -179,6 +179,7 @@ <flag name='input-linux'/> <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> + <flag name='virtio-iommu-pci'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml index f8317c1117..2398b2d50a 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml @@ -187,6 +187,7 @@ <flag name='input-linux'/> <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> + <flag name='virtio-iommu-pci'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml index d8f9af8af2..1feb49ef9f 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml @@ -172,6 +172,7 @@ <flag name='input-linux'/> <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> + <flag name='virtio-iommu-pci'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml index 3e99e52962..225afd7771 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml @@ -222,6 +222,7 @@ <flag name='input-linux'/> <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> + <flag name='virtio-iommu-pci'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml index 18b7897bfa..4b2b7f5ca9 100644 --- a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml @@ -225,6 +225,7 @@ <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> <flag name='virtio-mem-pci'/> + <flag name='virtio-iommu-pci'/> <version>5001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.aarch64.xml index b943eaedaf..ab40e2bdf8 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.aarch64.xml @@ -184,6 +184,7 @@ <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml index ec64e1cacf..ec8d29fe04 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml @@ -190,6 +190,7 @@ <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.riscv64.xml index 29ea8b1b8c..004e90ca5b 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.riscv64.xml @@ -175,6 +175,7 @@ <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.s390x.xml b/tests/qemucapabilitiesdata/caps_5.2.0.s390x.xml index 552e1d43c9..54132c807b 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.s390x.xml @@ -141,6 +141,7 @@ <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml index 923aa240ad..d92fc21fa0 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml @@ -228,6 +228,7 @@ <flag name='virtio-mem-pci'/> <flag name='piix4.acpi-root-pci-hotplug'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml index 0fefe64537..e298363b94 100644 --- a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml @@ -192,6 +192,7 @@ <flag name='set-action'/> <flag name='virtio-blk.queue-size'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>6000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml index 61685066b8..fc210bdd0c 100644 --- a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml @@ -149,6 +149,7 @@ <flag name='set-action'/> <flag name='virtio-blk.queue-size'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>6000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml index 78ede15fb3..1f72d2ab25 100644 --- a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml @@ -236,6 +236,7 @@ <flag name='virtio-mem-pci'/> <flag name='piix4.acpi-root-pci-hotplug'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>6000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml index 98c2fcedce..ddf71447d4 100644 --- a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml @@ -240,6 +240,7 @@ <flag name='piix4.acpi-root-pci-hotplug'/> <flag name='ich9.acpi-hotplug-bridge'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>6001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml index ae55a52767..78efae4fdb 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml @@ -204,6 +204,7 @@ <flag name='memory-backend-file.reserve'/> <flag name='device.json'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>6001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml index 5a46da0a6a..526c14208d 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml @@ -241,6 +241,7 @@ <flag name='ich9.acpi-hotplug-bridge'/> <flag name='device.json'/> <flag name='query-dirty-rate'/> + <flag name='virtio-iommu-pci'/> <version>6001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100244</microcodeVersion> -- 2.31.1

This capability detects the availability of the boot-bypass property of the virtio-iommu-pci device. This property was only introduced in QEMU 6.2 but, since the device has been around for much longer, we end up querying its properties for several more releases. As I don't have convenient access to the 10+ binaries necessary to regenerate the replies, I just put some fake data in there. NOTE: the QEMU 6.2 binaries were built from source trees where https://lists.gnu.org/archive/html/qemu-devel/2021-10/msg00161.html https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg07819.html had been applied. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 8 + src/qemu/qemu_capabilities.h | 1 + .../caps_5.0.0.aarch64.replies | 71 +++-- .../caps_5.0.0.ppc64.replies | 59 ++-- .../caps_5.0.0.riscv64.replies | 55 ++-- .../caps_5.0.0.x86_64.replies | 71 +++-- .../caps_5.1.0.x86_64.replies | 71 +++-- .../caps_5.2.0.aarch64.replies | 71 +++-- .../caps_5.2.0.ppc64.replies | 59 ++-- .../caps_5.2.0.riscv64.replies | 55 ++-- .../caps_5.2.0.s390x.replies | 59 ++-- .../caps_5.2.0.x86_64.replies | 71 +++-- .../caps_6.0.0.aarch64.replies | 71 +++-- .../caps_6.0.0.s390x.replies | 59 ++-- .../caps_6.0.0.x86_64.replies | 71 +++-- .../caps_6.1.0.x86_64.replies | 71 +++-- .../caps_6.2.0.aarch64.replies | 275 ++++++++++++++++-- .../caps_6.2.0.aarch64.xml | 1 + .../caps_6.2.0.x86_64.replies | 275 ++++++++++++++++-- .../caps_6.2.0.x86_64.xml | 1 + 20 files changed, 1099 insertions(+), 376 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 30eed6b1b9..4443fb6b19 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -652,6 +652,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "device.json", /* QEMU_CAPS_DEVICE_JSON */ "query-dirty-rate", /* QEMU_CAPS_QUERY_DIRTY_RATE */ "virtio-iommu-pci", /* QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI */ + "virtio-iommu.boot-bypass", /* QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS */ ); @@ -1552,6 +1553,10 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVhostUserFS[] = { "bootindex", QEMU_CAPS_VHOST_USER_FS_BOOTINDEX, NULL }, }; +static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVirtioIOMMU[] = { + { "boot-bypass", QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS, NULL }, +}; + /* see documentation for virQEMUQAPISchemaPathGet for the query format */ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = { { "block-commit/arg-type/*top", QEMU_CAPS_ACTIVE_COMMIT }, @@ -1711,6 +1716,9 @@ static virQEMUCapsDeviceTypeProps virQEMUCapsDeviceProps[] = { { "vhost-user-fs-device", virQEMUCapsDevicePropsVhostUserFS, G_N_ELEMENTS(virQEMUCapsDevicePropsVhostUserFS), QEMU_CAPS_DEVICE_VHOST_USER_FS }, + { "virtio-iommu-pci", virQEMUCapsDevicePropsVirtioIOMMU, + G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioIOMMU), + QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI }, }; static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMemoryBackendFile[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index d8417c1955..8b40344985 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -632,6 +632,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_DEVICE_JSON, /* -device accepts JSON */ QEMU_CAPS_QUERY_DIRTY_RATE, /* accepts query-dirty-rate */ QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI, /* -device virtio-iommu-pci */ + QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS, /* virtio-iommu.boot-bypass */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies index 574c14d4ce..29bde0357f 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies @@ -20244,12 +20244,31 @@ "id": "libvirt-32" } +{ + "execute": "device-list-properties", + "arguments": { + "typename": "virtio-iommu-pci" + }, + "id": "libvirt-33" +} + +{ + "return": [ + { + "name": "fake-data", + "description": "pretend there's real data here", + "type": "str" + } + ], + "id": "libvirt-33" +} [...] diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies index e8ce132f3c..80bf3a4eb5 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies @@ -24217,12 +24217,235 @@ "id": "libvirt-34" } +{ + "execute": "device-list-properties", + "arguments": { + "typename": "virtio-iommu-pci" + }, + "id": "libvirt-35" +} + +{ + "return": [ + { + "default-value": 1, + "name": "rombar", + "type": "uint32" + }, + { + "default-value": true, + "name": "x-pcie-lnksta-dllla", + "description": "on/off", + "type": "bool" + }, + { + "default-value": 4294967295, + "name": "romsize", + "type": "uint32" + }, + { + "default-value": false, + "name": "multifunction", + "description": "on/off", + "type": "bool" + }, + { + "default-value": 0, + "name": "acpi-index", + "type": "uint32" + }, + { + "name": "romfile", + "type": "str" + }, + { + "default-value": true, + "name": "x-pcie-extcap-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": -1, + "name": "addr", + "description": "Slot and optional function number, example: 06.0 or 06", + "type": "int32" + }, + { + "name": "failover_pair_id", + "type": "str" + }, + { + "default-value": false, + "name": "virtio-pci-bus-master-bug-migration", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-pcie-lnkctl-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-pcie-flr-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "x-ignore-backend-features", + "type": "bool" + }, + { + "default-value": false, + "name": "page-per-vq", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "migrate-extra", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-pcie-pm-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "modern-pio-notify", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-pcie-deverr-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "aer", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "ats", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "x-disable-pcie", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-ats-page-aligned", + "description": "on/off", + "type": "bool" + }, + { + "default-value": 0, + "name": "len-reserved-regions", + "type": "uint32" + }, + { + "default-value": 0, + "name": "class", + "type": "uint32" + }, + { + "default-value": false, + "name": "disable-modern", + "type": "bool" + }, + { + "default-value": "auto", + "name": "disable-legacy", + "description": "on/off/auto", + "type": "OnOffAuto" + }, + { + "default-value": true, + "name": "notify_on_empty", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "any_layout", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "indirect_desc", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "use-started", + "type": "bool" + }, + { + "default-value": true, + "name": "boot-bypass", + "type": "bool" + }, + { + "default-value": true, + "name": "event_idx", + "description": "on/off", + "type": "bool" + }, + { + "name": "primary-bus", + "type": "link<PCI>" + }, + { + "default-value": false, + "name": "x-disable-legacy-check", + "type": "bool" + }, + { + "name": "virtio-backend", + "type": "child<virtio-iommu-device>" + }, + { + "default-value": false, + "name": "iommu_platform", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "use-disabled-flag", + "type": "bool" + }, + { + "default-value": false, + "name": "packed", + "description": "on/off", + "type": "bool" + } + ], + "id": "libvirt-35" +} [...] diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml index 78efae4fdb..cc0349e1d2 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml @@ -205,6 +205,7 @@ <flag name='device.json'/> <flag name='query-dirty-rate'/> <flag name='virtio-iommu-pci'/> + <flag name='virtio-iommu.boot-bypass'/> <version>6001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies index aa7a779a68..a1ee80c6a1 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies @@ -23425,12 +23425,235 @@ "id": "libvirt-37" } +{ + "execute": "device-list-properties", + "arguments": { + "typename": "virtio-iommu-pci" + }, + "id": "libvirt-38" +} + +{ + "return": [ + { + "name": "failover_pair_id", + "type": "str" + }, + { + "name": "romfile", + "type": "str" + }, + { + "default-value": -1, + "name": "addr", + "description": "Slot and optional function number, example: 06.0 or 06", + "type": "int32" + }, + { + "default-value": 4294967295, + "name": "romsize", + "type": "uint32" + }, + { + "default-value": true, + "name": "x-pcie-lnksta-dllla", + "description": "on/off", + "type": "bool" + }, + { + "default-value": 1, + "name": "rombar", + "type": "uint32" + }, + { + "default-value": true, + "name": "x-pcie-extcap-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": 0, + "name": "acpi-index", + "type": "uint32" + }, + { + "default-value": false, + "name": "multifunction", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "migrate-extra", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "ats", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "x-ignore-backend-features", + "type": "bool" + }, + { + "default-value": true, + "name": "x-pcie-pm-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "aer", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-pcie-flr-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-pcie-lnkctl-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-ats-page-aligned", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "page-per-vq", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "x-pcie-deverr-init", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "virtio-pci-bus-master-bug-migration", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "modern-pio-notify", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "x-disable-pcie", + "description": "on/off", + "type": "bool" + }, + { + "default-value": 0, + "name": "len-reserved-regions", + "type": "uint32" + }, + { + "default-value": 0, + "name": "class", + "type": "uint32" + }, + { + "default-value": "auto", + "name": "disable-legacy", + "description": "on/off/auto", + "type": "OnOffAuto" + }, + { + "default-value": false, + "name": "disable-modern", + "type": "bool" + }, + { + "default-value": true, + "name": "use-disabled-flag", + "type": "bool" + }, + { + "name": "virtio-backend", + "type": "child<virtio-iommu-device>" + }, + { + "default-value": false, + "name": "packed", + "description": "on/off", + "type": "bool" + }, + { + "default-value": false, + "name": "iommu_platform", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "event_idx", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "boot-bypass", + "type": "bool" + }, + { + "default-value": false, + "name": "x-disable-legacy-check", + "type": "bool" + }, + { + "default-value": true, + "name": "notify_on_empty", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "any_layout", + "description": "on/off", + "type": "bool" + }, + { + "default-value": true, + "name": "use-started", + "type": "bool" + }, + { + "default-value": true, + "name": "indirect_desc", + "description": "on/off", + "type": "bool" + }, + { + "name": "primary-bus", + "type": "link<PCI>" + } + ], + "id": "libvirt-38" +} [...] diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml index 526c14208d..04432cde3b 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml @@ -242,6 +242,7 @@ <flag name='device.json'/> <flag name='query-dirty-rate'/> <flag name='virtio-iommu-pci'/> + <flag name='virtio-iommu.boot-bypass'/> <version>6001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100244</microcodeVersion> -- 2.31.1

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 4 ++++ src/qemu/qemu_domain_address.c | 6 ++++++ src/qemu/qemu_validate.c | 3 +++ 6 files changed, 16 insertions(+) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 26990c4d6d..4d6bf906fb 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5415,6 +5415,7 @@ <choice> <value>intel</value> <value>smmuv3</value> + <value>virtio</value> </choice> </attribute> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 15228d1e38..5102857d5e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1267,6 +1267,7 @@ VIR_ENUM_IMPL(virDomainIOMMUModel, VIR_DOMAIN_IOMMU_MODEL_LAST, "intel", "smmuv3", + "virtio", ); VIR_ENUM_IMPL(virDomainVsockModel, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 4624bad1f7..486f2f7a2e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2703,6 +2703,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainSecDef, virDomainSecDefFree); typedef enum { VIR_DOMAIN_IOMMU_MODEL_INTEL, VIR_DOMAIN_IOMMU_MODEL_SMMUV3, + VIR_DOMAIN_IOMMU_MODEL_VIRTIO, VIR_DOMAIN_IOMMU_MODEL_LAST } virDomainIOMMUModel; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 74e5bac7a2..41e487d056 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6564,6 +6564,9 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, return 0; + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + break; + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: /* There is no -device for SMMUv3, so nothing to be done here */ return 0; @@ -7159,6 +7162,7 @@ qemuBuildMachineCommandLine(virCommand *cmd, break; case VIR_DOMAIN_IOMMU_MODEL_INTEL: + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: /* These IOMMUs are formatted in qemuBuildIOMMUCommandLine */ break; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 733fa35444..e23de3bb83 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1003,6 +1003,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_IOMMU: switch ((virDomainIOMMUModel) dev->data.iommu->model) { + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + return 0; + case VIR_DOMAIN_IOMMU_MODEL_INTEL: case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: case VIR_DOMAIN_IOMMU_MODEL_LAST: @@ -2382,6 +2385,9 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, virDomainIOMMUDef *iommu = def->iommu; switch ((virDomainIOMMUModel) iommu->model) { + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + break; + case VIR_DOMAIN_IOMMU_MODEL_INTEL: case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 3045e4b64b..bd4c7b2cd7 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4869,6 +4869,9 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, } break; + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + break; + case VIR_DOMAIN_IOMMU_MODEL_LAST: default: virReportEnumRangeError(virDomainIOMMUModel, iommu->model); -- 2.31.1

These represent valid uses of the device. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- .../virtio-iommu-aarch64.aarch64-latest.args | 34 +++++++++++++++++++ .../qemuxml2argvdata/virtio-iommu-aarch64.xml | 20 +++++++++++ .../virtio-iommu-x86_64.x86_64-latest.args | 30 ++++++++++++++++ .../qemuxml2argvdata/virtio-iommu-x86_64.xml | 18 ++++++++++ tests/qemuxml2argvtest.c | 2 ++ .../virtio-iommu-aarch64.aarch64-latest.xml | 32 +++++++++++++++++ .../virtio-iommu-x86_64.x86_64-latest.xml | 34 +++++++++++++++++++ tests/qemuxml2xmltest.c | 2 ++ 8 files changed, 172 insertions(+) create mode 100644 tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args create mode 100644 tests/qemuxml2argvdata/virtio-iommu-aarch64.xml create mode 100644 tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/virtio-iommu-x86_64.xml create mode 100644 tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml diff --git a/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args b/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args new file mode 100644 index 0000000000..0363b0370d --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \ +/usr/bin/qemu-system-aarch64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/AAVMF/AAVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}' \ +-machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,memory-backend=mach-virt.ram \ +-cpu cortex-a15 \ +-m 1024 \ +-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-audiodev id=audio1,driver=none \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/virtio-iommu-aarch64.xml b/tests/qemuxml2argvdata/virtio-iommu-aarch64.xml new file mode 100644 index 0000000000..3e89cb2dac --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-aarch64.xml @@ -0,0 +1,20 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + <loader readonly='yes' type='pflash'>/usr/share/AAVMF/AAVMF_CODE.fd</loader> + <nvram>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + <iommu model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args b/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args new file mode 100644 index 0000000000..8a1413d33d --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args @@ -0,0 +1,30 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine q35,accel=tcg,usb=off,dump-guest-core=off,memory-backend=pc.ram \ +-cpu qemu64 \ +-m 214 \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-audiodev id=audio1,driver=none \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/virtio-iommu-x86_64.xml b/tests/qemuxml2argvdata/virtio-iommu-x86_64.xml new file mode 100644 index 0000000000..51c13d2ef6 --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-x86_64.xml @@ -0,0 +1,18 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + <iommu model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index e209b48fce..60d44eea01 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3252,6 +3252,8 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-aw-bits"); DO_TEST_CAPS_LATEST_PARSE_ERROR("intel-iommu-wrong-machine"); DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64"); + DO_TEST_CAPS_LATEST("virtio-iommu-x86_64"); + DO_TEST_CAPS_ARCH_LATEST("virtio-iommu-aarch64", "aarch64"); DO_TEST("cpu-hotplug-startup", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS); DO_TEST_PARSE_ERROR("cpu-hotplug-granularity", diff --git a/tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml b/tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml new file mode 100644 index 0000000000..336f99d539 --- /dev/null +++ b/tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + <loader readonly='yes' type='pflash'>/usr/share/AAVMF/AAVMF_CODE.fd</loader> + <nvram>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <gic version='2'/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>cortex-a15</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <controller type='usb' index='0' model='none'/> + <controller type='pci' index='0' model='pcie-root'/> + <audio id='1' type='none'/> + <memballoon model='none'/> + <iommu model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml b/tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml new file mode 100644 index 0000000000..0b6c2d0eaf --- /dev/null +++ b/tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml @@ -0,0 +1,34 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='none'/> + <iommu model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index b0a1212a54..3d9e3bb437 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1302,6 +1302,8 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-device-iotlb"); DO_TEST_CAPS_LATEST("intel-iommu-aw-bits"); DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64"); + DO_TEST_CAPS_LATEST("virtio-iommu-x86_64"); + DO_TEST_CAPS_ARCH_LATEST("virtio-iommu-aarch64", "aarch64"); DO_TEST_NOCAPS("cpu-check-none"); DO_TEST_NOCAPS("cpu-check-partial"); -- 2.31.1

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_validate.c | 8 ++++++++ ...irtio-iommu-wrong-machine.x86_64-latest.err | 1 + .../virtio-iommu-wrong-machine.xml | 18 ++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 28 insertions(+) create mode 100644 tests/qemuxml2argvdata/virtio-iommu-wrong-machine.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-wrong-machine.xml diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index bd4c7b2cd7..4f35e0eb49 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4870,6 +4870,14 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, break; case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + if (!qemuDomainIsARMVirt(def) && + !qemuDomainIsQ35(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' is only supported with " + "Q35 and ARM Virt machines"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } break; case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/tests/qemuxml2argvdata/virtio-iommu-wrong-machine.x86_64-latest.err b/tests/qemuxml2argvdata/virtio-iommu-wrong-machine.x86_64-latest.err new file mode 100644 index 0000000000..8d1cd19170 --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-wrong-machine.x86_64-latest.err @@ -0,0 +1 @@ +unsupported configuration: IOMMU device: 'virtio' is only supported with Q35 and ARM Virt machines diff --git a/tests/qemuxml2argvdata/virtio-iommu-wrong-machine.xml b/tests/qemuxml2argvdata/virtio-iommu-wrong-machine.xml new file mode 100644 index 0000000000..ad2a516b3a --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-wrong-machine.xml @@ -0,0 +1,18 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + <iommu model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 60d44eea01..ff3832b642 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3254,6 +3254,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64"); DO_TEST_CAPS_LATEST("virtio-iommu-x86_64"); DO_TEST_CAPS_ARCH_LATEST("virtio-iommu-aarch64", "aarch64"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-wrong-machine"); DO_TEST("cpu-hotplug-startup", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS); DO_TEST_PARSE_ERROR("cpu-hotplug-granularity", -- 2.31.1

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_validate.c | 8 ++++++++ .../qemuxml2argvdata/virtio-iommu-x86_64.x86_64-6.1.0.err | 1 + tests/qemuxml2argvtest.c | 1 + 3 files changed, 10 insertions(+) create mode 100644 tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-6.1.0.err diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 4f35e0eb49..7bee9fa9b0 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4878,6 +4878,14 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, virDomainIOMMUModelTypeToString(iommu->model)); return -1; } + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI) || + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' is not supported with " + "this QEMU binary"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } break; case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-6.1.0.err b/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-6.1.0.err new file mode 100644 index 0000000000..e76e1540bc --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-6.1.0.err @@ -0,0 +1 @@ +unsupported configuration: IOMMU device: 'virtio' is not supported with this QEMU binary diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ff3832b642..ce57661d4c 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3253,6 +3253,7 @@ mymain(void) DO_TEST_CAPS_LATEST_PARSE_ERROR("intel-iommu-wrong-machine"); DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64"); DO_TEST_CAPS_LATEST("virtio-iommu-x86_64"); + DO_TEST_CAPS_VER_PARSE_ERROR("virtio-iommu-x86_64", "6.1.0"); DO_TEST_CAPS_ARCH_LATEST("virtio-iommu-aarch64", "aarch64"); DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-wrong-machine"); -- 2.31.1

virtio-iommu doesn't work without ACPI, so we need to make sure the latter is enabled. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_validate.c | 6 ++++++ .../virtio-iommu-no-acpi.x86_64-latest.err | 1 + tests/qemuxml2argvdata/virtio-iommu-no-acpi.xml | 15 +++++++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 23 insertions(+) create mode 100644 tests/qemuxml2argvdata/virtio-iommu-no-acpi.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-no-acpi.xml diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 7bee9fa9b0..0250f3e537 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4886,6 +4886,12 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, virDomainIOMMUModelTypeToString(iommu->model)); return -1; } + if (def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' requires ACPI"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } break; case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/tests/qemuxml2argvdata/virtio-iommu-no-acpi.x86_64-latest.err b/tests/qemuxml2argvdata/virtio-iommu-no-acpi.x86_64-latest.err new file mode 100644 index 0000000000..6b598951bb --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-no-acpi.x86_64-latest.err @@ -0,0 +1 @@ +unsupported configuration: IOMMU device: 'virtio' requires ACPI diff --git a/tests/qemuxml2argvdata/virtio-iommu-no-acpi.xml b/tests/qemuxml2argvdata/virtio-iommu-no-acpi.xml new file mode 100644 index 0000000000..36e5eb39b9 --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-no-acpi.xml @@ -0,0 +1,15 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + </os> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + <iommu model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ce57661d4c..8b13064e58 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3256,6 +3256,7 @@ mymain(void) DO_TEST_CAPS_VER_PARSE_ERROR("virtio-iommu-x86_64", "6.1.0"); DO_TEST_CAPS_ARCH_LATEST("virtio-iommu-aarch64", "aarch64"); DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-wrong-machine"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-no-acpi"); DO_TEST("cpu-hotplug-startup", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS); DO_TEST_PARSE_ERROR("cpu-hotplug-granularity", -- 2.31.1

This is needed so that IOMMU devices can have addresses. Existing IOMMU devices (intel-iommu and SMMUv3) are system devices and as such don't have an address associated to them, but virtio-iommu is a PCI device and needs one. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/schemas/domaincommon.rng | 63 +++++++++++++++++++---------------- src/conf/domain_conf.c | 37 +++++++++++++------- src/conf/domain_conf.h | 1 + 3 files changed, 60 insertions(+), 41 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4d6bf906fb..f19c4eeb21 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5418,35 +5418,40 @@ <value>virtio</value> </choice> </attribute> - <optional> - <element name="driver"> - <optional> - <attribute name="intremap"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="caching_mode"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="eim"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="iotlb"> - <ref name="virOnOff"/> - </attribute> - </optional> - <optional> - <attribute name="aw_bits"> - <ref name="uint8"/> - </attribute> - </optional> - </element> - </optional> + <interleave> + <optional> + <element name="driver"> + <optional> + <attribute name="intremap"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="caching_mode"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="eim"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="iotlb"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="aw_bits"> + <ref name="uint8"/> + </attribute> + </optional> + </element> + </optional> + <optional> + <ref name="address"/> + </optional> + </interleave> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5102857d5e..146c11bb47 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2552,6 +2552,7 @@ virDomainIOMMUDefFree(virDomainIOMMUDef *iommu) if (!iommu) return; + virDomainDeviceInfoClear(&iommu->info); g_free(iommu); } @@ -4241,13 +4242,14 @@ virDomainDeviceGetInfo(const virDomainDeviceDef *device) return &device->data.panic->info; case VIR_DOMAIN_DEVICE_MEMORY: return &device->data.memory->info; + case VIR_DOMAIN_DEVICE_IOMMU: + return &device->data.iommu->info; case VIR_DOMAIN_DEVICE_VSOCK: return &device->data.vsock->info; /* The following devices do not contain virDomainDeviceInfo */ case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_GRAPHICS: - case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_LAST: case VIR_DOMAIN_DEVICE_NONE: @@ -4543,6 +4545,13 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def, return rc; } + device.type = VIR_DOMAIN_DEVICE_IOMMU; + if (def->iommu) { + device.data.iommu = def->iommu; + if ((rc = cb(def, &device, &def->iommu->info, opaque)) != 0) + return rc; + } + device.type = VIR_DOMAIN_DEVICE_VSOCK; if (def->vsock) { device.data.vsock = def->vsock; @@ -4570,12 +4579,6 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def, if ((rc = cb(def, &device, NULL, opaque)) != 0) return rc; } - device.type = VIR_DOMAIN_DEVICE_IOMMU; - if (def->iommu) { - device.data.iommu = def->iommu; - if ((rc = cb(def, &device, NULL, opaque)) != 0) - return rc; - } } /* Coverity is not very happy with this - all dead_error_condition */ @@ -14940,8 +14943,10 @@ virDomainMemoryDefParseXML(virDomainXMLOption *xmlopt, static virDomainIOMMUDef * -virDomainIOMMUDefParseXML(xmlNodePtr node, - xmlXPathContextPtr ctxt) +virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, + xmlNodePtr node, + xmlXPathContextPtr ctxt, + unsigned int flags) { VIR_XPATH_NODE_AUTORESTORE(ctxt) xmlNodePtr driver; @@ -14977,6 +14982,10 @@ virDomainIOMMUDefParseXML(xmlNodePtr node, return NULL; } + if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, + &iommu->info, flags) < 0) + return NULL; + return g_steal_pointer(&iommu); } @@ -15174,7 +15183,8 @@ virDomainDeviceDefParse(const char *xmlStr, return NULL; break; case VIR_DOMAIN_DEVICE_IOMMU: - if (!(dev->data.iommu = virDomainIOMMUDefParseXML(node, ctxt))) + if (!(dev->data.iommu = virDomainIOMMUDefParseXML(xmlopt, node, + ctxt, flags))) return NULL; break; case VIR_DOMAIN_DEVICE_VSOCK: @@ -20325,7 +20335,8 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt, } if (n > 0) { - if (!(def->iommu = virDomainIOMMUDefParseXML(nodes[0], ctxt))) + if (!(def->iommu = virDomainIOMMUDefParseXML(xmlopt, nodes[0], + ctxt, flags))) return NULL; } VIR_FREE(nodes); @@ -22179,7 +22190,7 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, return false; } - return true; + return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); } @@ -27566,6 +27577,8 @@ virDomainIOMMUDefFormat(virBuffer *buf, virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL); + virDomainDeviceInfoFormat(&childBuf, &iommu->info, 0); + virBufferAsprintf(&attrBuf, " model='%s'", virDomainIOMMUModelTypeToString(iommu->model)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 486f2f7a2e..d8621e2d4f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2715,6 +2715,7 @@ struct _virDomainIOMMUDef { virTristateSwitch eim; virTristateSwitch iotlb; unsigned int aw_bits; + virDomainDeviceInfo info; }; typedef enum { -- 2.31.1

The device is configured to be an integrated endpoint, as is necessary for it to function correctly. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain_address.c | 6 +++++- .../virtio-iommu-aarch64.aarch64-latest.xml | 4 +++- .../virtio-iommu-x86_64.x86_64-latest.xml | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index e23de3bb83..767e2c28f8 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1004,7 +1004,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_IOMMU: switch ((virDomainIOMMUModel) dev->data.iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: - return 0; + return virtioFlags | VIR_PCI_CONNECT_INTEGRATED; case VIR_DOMAIN_IOMMU_MODEL_INTEL: case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: @@ -2386,6 +2386,10 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, switch ((virDomainIOMMUModel) iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + if (virDeviceInfoPCIAddressIsWanted(&iommu->info) && + qemuDomainPCIAddressReserveNextAddr(addrs, &iommu->info) < 0) { + return -1; + } break; case VIR_DOMAIN_IOMMU_MODEL_INTEL: diff --git a/tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml b/tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml index 336f99d539..c6560e9a91 100644 --- a/tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml +++ b/tests/qemuxml2xmloutdata/virtio-iommu-aarch64.aarch64-latest.xml @@ -27,6 +27,8 @@ <controller type='pci' index='0' model='pcie-root'/> <audio id='1' type='none'/> <memballoon model='none'/> - <iommu model='virtio'/> + <iommu model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </iommu> </devices> </domain> diff --git a/tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml b/tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml index 0b6c2d0eaf..ad3a702b0b 100644 --- a/tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/virtio-iommu-x86_64.x86_64-latest.xml @@ -29,6 +29,8 @@ <input type='keyboard' bus='ps2'/> <audio id='1' type='none'/> <memballoon model='none'/> - <iommu model='virtio'/> + <iommu model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </iommu> </devices> </domain> -- 2.31.1

virtio-iommu is a PCI device and attempts to use a different address type should be rejected. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_validate.c | 7 +++++++ ...mmu-invalid-address-type.x86_64-latest.err | 1 + .../virtio-iommu-invalid-address-type.xml | 20 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 29 insertions(+) create mode 100644 tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.xml diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 0250f3e537..f16dc9d42b 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4892,6 +4892,13 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, virDomainIOMMUModelTypeToString(iommu->model)); return -1; } + if (iommu->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + iommu->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' needs a PCI address"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } break; case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.x86_64-latest.err b/tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.x86_64-latest.err new file mode 100644 index 0000000000..216848eaf8 --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.x86_64-latest.err @@ -0,0 +1 @@ +unsupported configuration: IOMMU device: 'virtio' needs a PCI address diff --git a/tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.xml b/tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.xml new file mode 100644 index 0000000000..8c227c38a4 --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-invalid-address-type.xml @@ -0,0 +1,20 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + <iommu model='virtio'> + <address type='virtio-mmio'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 8b13064e58..c5697c8b75 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3257,6 +3257,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("virtio-iommu-aarch64", "aarch64"); DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-wrong-machine"); DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-no-acpi"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-invalid-address-type"); DO_TEST("cpu-hotplug-startup", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS); DO_TEST_PARSE_ERROR("cpu-hotplug-granularity", -- 2.31.1

virtio-iommu needs to be an integrated device, and our address assignment code will make sure that is the case. If the user has provided an explicit address, however, we should make sure any addresses pointing to a different bus are rejected. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...io-iommu-invalid-address.x86_64-latest.err | 1 + .../virtio-iommu-invalid-address.xml | 20 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 3 files changed, 22 insertions(+) create mode 100644 tests/qemuxml2argvdata/virtio-iommu-invalid-address.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/virtio-iommu-invalid-address.xml diff --git a/tests/qemuxml2argvdata/virtio-iommu-invalid-address.x86_64-latest.err b/tests/qemuxml2argvdata/virtio-iommu-invalid-address.x86_64-latest.err new file mode 100644 index 0000000000..997948e91f --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-invalid-address.x86_64-latest.err @@ -0,0 +1 @@ +XML error: The device at PCI address 0000:01:00.0 needs to be an integrated device (bus=0) diff --git a/tests/qemuxml2argvdata/virtio-iommu-invalid-address.xml b/tests/qemuxml2argvdata/virtio-iommu-invalid-address.xml new file mode 100644 index 0000000000..0daa58e3e7 --- /dev/null +++ b/tests/qemuxml2argvdata/virtio-iommu-invalid-address.xml @@ -0,0 +1,20 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + <iommu model='virtio'> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c5697c8b75..0e6d5ab9ad 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3258,6 +3258,7 @@ mymain(void) DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-wrong-machine"); DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-no-acpi"); DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-invalid-address-type"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-invalid-address"); DO_TEST("cpu-hotplug-startup", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS); DO_TEST_PARSE_ERROR("cpu-hotplug-granularity", -- 2.31.1

https://bugzilla.redhat.com/show_bug.cgi?id=1653327 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 12 +++++++++++- .../virtio-iommu-aarch64.aarch64-latest.args | 1 + .../virtio-iommu-x86_64.x86_64-latest.args | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 41e487d056..97be569892 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -953,6 +953,7 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device, break; case VIR_DOMAIN_DEVICE_IOMMU: + *baseName = "virtio-iommu"; break; case VIR_DOMAIN_DEVICE_LEASE: @@ -6565,7 +6566,16 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, return 0; case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: - break; + if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_IOMMU, iommu, qemuCaps))) + return -1; + + if (qemuBuildDeviceAddressProps(props, def, &iommu->info) < 0) + return -1; + + if (qemuBuildDeviceCommandlineFromJSON(cmd, props, qemuCaps) < 0) + return -1; + + return 0; case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: /* There is no -device for SMMUv3, so nothing to be done here */ diff --git a/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args b/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args index 0363b0370d..343af7b2a1 100644 --- a/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args +++ b/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args @@ -29,6 +29,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ +-device '{"driver":"virtio-iommu-pci","bus":"pcie.0","addr":"0x1"}' \ -audiodev id=audio1,driver=none \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args b/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args index 8a1413d33d..9fcc76f7b3 100644 --- a/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args +++ b/tests/qemuxml2argvdata/virtio-iommu-x86_64.x86_64-latest.args @@ -25,6 +25,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ +-device '{"driver":"virtio-iommu-pci","bus":"pcie.0","addr":"0x1"}' \ -audiodev id=audio1,driver=none \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on -- 2.31.1

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/formatdomain.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 9bf59936e5..ed9fc735a5 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7986,8 +7986,9 @@ Example: ... ``model`` - Supported values are ``intel`` (for Q35 guests) and, :since:`since 5.5.0` , - ``smmuv3`` (for ARM virt guests). + Supported values are ``intel`` (for Q35 guests) ``smmuv3`` + (:since:`since 5.5.0`, for ARM virt guests), and ``virtio`` + (:since:`since 7.9.0`, for Q35 and ARM virt guests). ``driver`` The ``driver`` subelement can be used to configure additional options, some -- 2.31.1

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- NEWS.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index f3b9e5f0cb..07971a6c42 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -40,6 +40,10 @@ v7.9.0 (unreleased) domain definition when the guest was first started).This setting is only applicable for x86 guests using qemu driver. + * qemu: Introduce support for virtio-iommu + + This IOMMU device can be used with both Q35 and ARM virt guests. + * **Improvements** * Use of JSON syntax with ``-device`` with upcoming QEMU-6.2 -- 2.31.1

On a Wednesday in 2021, Andrea Bolognani wrote:
The first patch adds QEMU replies and as such has been aggressively snipped to deal with mailing list message size limits. Grab the unabriged version with
$ git fetch https://gitlab.com/abologna/libvirt.git virtio-iommu
As noted in patch 10, the QEMU feature this series enables has not yet been accepted upstream: the relevant patches are
https://lists.gnu.org/archive/html/qemu-devel/2021-10/msg00161.html https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg07819.html
and of course this series should only be merged once those have gone in.
That said, patches 1-6 are necessary to implement the feature but also not strictly related to it, so they could be merged right away.
Changes from [v1]:
* rebased after Peter's recent changes enabling JSON for -device.
[v1] https://listman.redhat.com/archives/libvir-list/2021-October/msg00459.html
Andrea Bolognani (22): tests: Add replies for QEMU 6.2.0 on aarch64 conf: Make virDomainDeviceInfoFormat() const correct qemu: Make qemuBuildDeviceAddressProps() const correct qemu: Make qemuBuildVirtioDevProps() const correct conf: Add IOMMU support to virDomainDeviceDefCopy() conf: Add new/free functions for virDomainIOMMUDef conf: Introduce VIR_PCI_CONNECT_INTEGRATED qemu: Tweak some code
Patches up to here can be pushed already.
qemu: Introduce QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI DONOTMERGEYET: qemu: Introduce QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS conf: Introduce virtio model for <iommu> tests: Add test cases for virtio-iommu qemu: Validate machine type used with virtio-iommu qemu: Validate capabilities for virtio-iommu qemu: Validate use of ACPI with virtio-iommu conf: Add virDomainDeviceInfo to virDomainIOMMUDef qemu: Assign PCI address to virtio-iommu qemu: Validate address type for virtio-iommu tests: Add test for virtio-iommu address qemu: Generate command line for virtio-iommu docs: Document virtio-iommu news: Document virtio-iommu
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

On Wed, Oct 20, 2021 at 03:44:48PM +0200, Ján Tomko wrote:
On a Wednesday in 2021, Andrea Bolognani wrote:
tests: Add replies for QEMU 6.2.0 on aarch64 conf: Make virDomainDeviceInfoFormat() const correct qemu: Make qemuBuildDeviceAddressProps() const correct qemu: Make qemuBuildVirtioDevProps() const correct conf: Add IOMMU support to virDomainDeviceDefCopy() conf: Add new/free functions for virDomainIOMMUDef conf: Introduce VIR_PCI_CONNECT_INTEGRATED qemu: Tweak some code
Patches up to here can be pushed already.
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Thanks a lot for the review! I've only pushed patches 1-6 for now, because I don't feel that 7-8 make a lot of sense without the rest of the series and they have a low chance of bitrotting anyway. I'll just wait for the QEMU feature to be merged and then push the remaining patches all at once :) -- Andrea Bolognani / Red Hat / Virtualization
participants (2)
-
Andrea Bolognani
-
Ján Tomko