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

The first couple of patches add replies files and as such have 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 those patches, some of the QEMU changes this series depends on have 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. Andrea Bolognani (21): DONOTMERGEYET: Add replies for QEMU 6.2.0 on x86_64 DONOTMERGEYET: Add replies for QEMU 6.2.0 on aarch64 conf: Make virDomainDeviceInfoFormat() const correct conf: Introduce VIR_PCI_CONNECT_INTEGRATED conf: Add IOMMU support to virDomainDeviceDefCopy() conf: Add new/free functions for virDomainIOMMUDef qemu: Tweak some code qemu: Introduce QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI 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 | 35 +- src/qemu/qemu_domain_address.c | 33 +- src/qemu/qemu_validate.c | 32 + .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 220 + .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 226 + .../qemu_6.2.0-virt.aarch64.xml | 184 + tests/domaincapsdata/qemu_6.2.0.aarch64.xml | 178 + tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 220 + .../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} | 5621 ++++++++++------- ...0.0.aarch64.xml => caps_6.2.0.aarch64.xml} | 57 +- ...6_64.replies => caps_6.2.0.x86_64.replies} | 4154 +++++++----- ...6.1.0.x86_64.xml => caps_6.2.0.x86_64.xml} | 85 +- .../virtio-iommu-aarch64.aarch64-latest.args | 35 + .../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 + 66 files changed, 8192 insertions(+), 4257 deletions(-) create mode 100644 tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml create mode 100644 tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml 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/domaincapsdata/qemu_6.2.0.x86_64.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/qemucapabilitiesdata/{caps_6.1.0.x86_64.replies => caps_6.2.0.x86_64.replies} (96%) copy tests/qemucapabilitiesdata/{caps_6.1.0.x86_64.xml => caps_6.2.0.x86_64.xml} (97%) 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-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-1220-g5564f06816 with https://lists.gnu.org/archive/html/qemu-devel/2021-10/msg00161.html https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg07819.html applied on top. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 220 + .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 226 + tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 220 + .../caps_6.2.0.x86_64.replies | 34273 ++++++++++++++++ .../caps_6.2.0.x86_64.xml | 3722 ++ 5 files changed, 38661 insertions(+) create mode 100644 tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml create mode 100644 tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml create mode 100644 tests/domaincapsdata/qemu_6.2.0.x86_64.xml create mode 100644 tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies create mode 100644 tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml diff --git a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml new file mode 100644 index 0000000000..df8bdae102 --- /dev/null +++ b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml @@ -0,0 +1,220 @@ +<domainCapabilities> + <path>/usr/bin/qemu-system-x86_64</path> + <domain>kvm</domain> + <machine>pc-q35-6.2</machine> + <arch>x86_64</arch> [...] diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies new file mode 100644 index 0000000000..53af711c9b --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies @@ -0,0 +1,34273 @@ +{ + "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": "v6.1.0-1234-gd27a3d1b9e-dirty" + }, + "id": "libvirt-2" +} [...] -- 2.31.1

These were generated using a QEMU binary built from commit v6.1.0-1220-g5564f06816 with https://lists.gnu.org/archive/html/qemu-devel/2021-10/msg00161.html https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg07819.html applied on top. 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 | 28671 ++++++++++++++++ .../caps_6.2.0.aarch64.xml | 541 + 4 files changed, 29574 insertions(+) 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/domaincapsdata/qemu_6.2.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml new file mode 100644 index 0000000000..4eb8209b07 --- /dev/null +++ b/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml @@ -0,0 +1,184 @@ +<domainCapabilities> + <path>/usr/bin/qemu-system-aarch64</path> + <domain>kvm</domain> + <machine>virt-6.2</machine> + <arch>aarch64</arch> [...] 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..59a0c4ff55 --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies @@ -0,0 +1,28671 @@ +{ + "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" +} [...] -- 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 b8370f6950..df51d59e0d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6319,7 +6319,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

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

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 df51d59e0d..60f2b1129f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -29588,6 +29588,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; @@ -29600,7 +29604,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 60f2b1129f..6df981ad47 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2524,6 +2524,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) { @@ -3325,7 +3346,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); @@ -3663,7 +3684,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); @@ -14916,11 +14937,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 c23c233184..72db861105 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3291,6 +3291,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

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 | 14 ++++++-------- src/qemu/qemu_domain_address.c | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 28bca1519c..bb743e3d84 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6206,15 +6206,14 @@ static int qemuBuildIOMMUCommandLine(virCommand *cmd, const virDomainDef *def) { + g_auto(virBuffer) opts = VIR_BUFFER_INITIALIZER; const virDomainIOMMUDef *iommu = def->iommu; if (!iommu) return 0; switch (iommu->model) { - case VIR_DOMAIN_IOMMU_MODEL_INTEL: { - g_auto(virBuffer) opts = VIR_BUFFER_INITIALIZER; - + case VIR_DOMAIN_IOMMU_MODEL_INTEL: virBufferAddLit(&opts, "intel-iommu"); if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&opts, ",intremap=%s", @@ -6238,7 +6237,6 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, virCommandAddArg(cmd, "-device"); virCommandAddArgBuffer(cmd, &opts); break; - } case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: /* There is no -device for SMMUv3, so nothing to be done here */ @@ -6848,14 +6846,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 82687dbf39..bfd02e866f 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -644,6 +644,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-mem-pci", /* QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI */ "memory-backend-file.reserve", /* QEMU_CAPS_MEMORY_BACKEND_RESERVE */ "piix4.acpi-root-pci-hotplug", /* QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG */ + "virtio-iommu-pci", /* QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI */ ); @@ -1359,6 +1360,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 2bbfc15dc4..e2611a6193 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -624,6 +624,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI, /* -device virtio-mem-pci */ QEMU_CAPS_MEMORY_BACKEND_RESERVE, /* -object memory-backend-*.reserve= */ QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG, /* -M pc PIIX4_PM.acpi-root-pci-hotplug */ + 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 2c125044de..083ed23eb2 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml @@ -184,6 +184,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 ce0f63c2b8..d0a1320400 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml @@ -192,6 +192,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 05c8e0e467..2ec45d95aa 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml @@ -177,6 +177,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 aae5fe018f..2c5f438d48 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml @@ -227,6 +227,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 e9ae3c5abb..4480b80c54 100644 --- a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml @@ -230,6 +230,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 59e1f746ca..6a341dc6d5 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.aarch64.xml @@ -188,6 +188,7 @@ <flag name='input-linux'/> <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> + <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 0ce8a5ba2f..b5af8cff63 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.ppc64.xml @@ -194,6 +194,7 @@ <flag name='input-linux'/> <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> + <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 1219ba2666..eeefa7c0da 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.riscv64.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>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 db92662f4c..54cf95ab9a 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.s390x.xml @@ -145,6 +145,7 @@ <flag name='input-linux'/> <flag name='query-display-options'/> <flag name='virtio-blk.queue-size'/> + <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 98b5f34f2b..45eaf5b702 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml @@ -232,6 +232,7 @@ <flag name='virtio-blk.queue-size'/> <flag name='virtio-mem-pci'/> <flag name='piix4.acpi-root-pci-hotplug'/> + <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 6a9833a176..e20e56eea5 100644 --- a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml @@ -196,6 +196,7 @@ <flag name='query-display-options'/> <flag name='set-action'/> <flag name='virtio-blk.queue-size'/> + <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 a96c756ef8..c2c5a2747d 100644 --- a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml @@ -153,6 +153,7 @@ <flag name='s390-pv-guest'/> <flag name='set-action'/> <flag name='virtio-blk.queue-size'/> + <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 f13a909314..fdb7957fb3 100644 --- a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml @@ -240,6 +240,7 @@ <flag name='virtio-blk.queue-size'/> <flag name='virtio-mem-pci'/> <flag name='piix4.acpi-root-pci-hotplug'/> + <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 87b37a2b7c..bdbced6860 100644 --- a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml @@ -243,6 +243,7 @@ <flag name='virtio-mem-pci'/> <flag name='memory-backend-file.reserve'/> <flag name='piix4.acpi-root-pci-hotplug'/> + <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 1e74d24f42..f2a083375e 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml @@ -207,6 +207,7 @@ <flag name='set-action'/> <flag name='virtio-blk.queue-size'/> <flag name='memory-backend-file.reserve'/> + <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 d1a55ac10c..60a1f34795 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml @@ -243,6 +243,7 @@ <flag name='virtio-mem-pci'/> <flag name='memory-backend-file.reserve'/> <flag name='piix4.acpi-root-pci-hotplug'/> + <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. 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 bfd02e866f..4b46707fc0 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -645,6 +645,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "memory-backend-file.reserve", /* QEMU_CAPS_MEMORY_BACKEND_RESERVE */ "piix4.acpi-root-pci-hotplug", /* QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG */ "virtio-iommu-pci", /* QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI */ + "virtio-iommu.boot-bypass", /* QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS */ ); @@ -1556,6 +1557,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 }, @@ -1714,6 +1719,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 e2611a6193..fc2e819688 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -625,6 +625,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_MEMORY_BACKEND_RESERVE, /* -object memory-backend-*.reserve= */ QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG, /* -M pc PIIX4_PM.acpi-root-pci-hotplug */ 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 59a0c4ff55..a46b27e11c 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.replies @@ -24190,12 +24190,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 f2a083375e..cc2286bf78 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml @@ -208,6 +208,7 @@ <flag name='virtio-blk.queue-size'/> <flag name='memory-backend-file.reserve'/> <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.xml b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml index 60a1f34795..e31089338e 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml @@ -244,6 +244,7 @@ <flag name='memory-backend-file.reserve'/> <flag name='piix4.acpi-root-pci-hotplug'/> <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 ec5bd91740..2f30b15c48 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 6df981ad47..a2d155069f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1261,6 +1261,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 72db861105..21e069f42e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2696,6 +2696,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 bb743e3d84..ef5ebe6413 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6238,6 +6238,9 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, virCommandAddArgBuffer(cmd, &opts); break; + 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; @@ -6851,6 +6854,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 c84508cb64..4646cd2af3 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4797,6 +4797,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 7df3946751..5f07c09d57 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3238,6 +3238,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 69363ef85c..d8bfa01f44 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1301,6 +1301,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 4646cd2af3..073f7bce58 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4798,6 +4798,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 5f07c09d57..72ffac5de3 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3240,6 +3240,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 073f7bce58..fd08a84fd6 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4806,6 +4806,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 72ffac5de3..75ea4d32f3 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3239,6 +3239,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 fd08a84fd6..816320944a 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4814,6 +4814,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 75ea4d32f3..d14f017098 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3242,6 +3242,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 2f30b15c48..6dffe3afae 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 a2d155069f..3b23c32a96 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2542,6 +2542,7 @@ virDomainIOMMUDefFree(virDomainIOMMUDef *iommu) if (!iommu) return; + virDomainDeviceInfoClear(&iommu->info); g_free(iommu); } @@ -4230,13 +4231,14 @@ virDomainDeviceGetInfo(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: @@ -4532,6 +4534,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; @@ -4559,12 +4568,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 */ @@ -14933,8 +14936,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; @@ -14970,6 +14975,10 @@ virDomainIOMMUDefParseXML(xmlNodePtr node, return NULL; } + if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, + &iommu->info, flags) < 0) + return NULL; + return g_steal_pointer(&iommu); } @@ -15167,7 +15176,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: @@ -20285,7 +20295,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); @@ -22107,7 +22118,7 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, return false; } - return true; + return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); } @@ -27494,6 +27505,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 21e069f42e..1961a686e6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2708,6 +2708,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 816320944a..7c18963a33 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4820,6 +4820,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 d14f017098..0d349567a5 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3243,6 +3243,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 0d349567a5..8a5b986e1b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3244,6 +3244,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 | 17 ++++++++++++++--- .../virtio-iommu-aarch64.aarch64-latest.args | 1 + .../virtio-iommu-x86_64.x86_64-latest.args | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ef5ebe6413..9941e2a10b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6204,10 +6204,11 @@ qemuBuildBootCommandLine(virCommand *cmd, static int qemuBuildIOMMUCommandLine(virCommand *cmd, - const virDomainDef *def) + const virDomainDef *def, + virQEMUCaps *qemuCaps) { g_auto(virBuffer) opts = VIR_BUFFER_INITIALIZER; - const virDomainIOMMUDef *iommu = def->iommu; + virDomainIOMMUDef *iommu = def->iommu; if (!iommu) return 0; @@ -6239,6 +6240,16 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, break; case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + if (qemuBuildVirtioDevStr(&opts, "virtio-iommu", qemuCaps, + VIR_DOMAIN_DEVICE_IOMMU, iommu) < 0) { + return -1; + } + + if (qemuBuildDeviceAddressStr(&opts, def, &iommu->info) < 0) + return -1; + + virCommandAddArg(cmd, "-device"); + virCommandAddArgBuffer(cmd, &opts); break; case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: @@ -10493,7 +10504,7 @@ qemuBuildCommandLine(virQEMUDriver *driver, if (qemuBuildBootCommandLine(cmd, def) < 0) return NULL; - if (qemuBuildIOMMUCommandLine(cmd, def) < 0) + if (qemuBuildIOMMUCommandLine(cmd, def, qemuCaps) < 0) return NULL; if (qemuBuildGlobalControllerCommandLine(cmd, def) < 0) diff --git a/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args b/tests/qemuxml2argvdata/virtio-iommu-aarch64.aarch64-latest.args index 0363b0370d..3f33abd696 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 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..7249d29b93 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 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

On Fri, Oct 08, 2021 at 18:51:54 +0200, Andrea Bolognani wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1653327
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 17 ++++++++++++++--- .../virtio-iommu-aarch64.aarch64-latest.args | 1 + .../virtio-iommu-x86_64.x86_64-latest.args | 1 + 3 files changed, 16 insertions(+), 3 deletions(-)
@@ -6239,6 +6240,16 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, break;
case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + if (qemuBuildVirtioDevStr(&opts, "virtio-iommu", qemuCaps, + VIR_DOMAIN_DEVICE_IOMMU, iommu) < 0) { + return -1; + } + + if (qemuBuildDeviceAddressStr(&opts, def, &iommu->info) < 0) + return -1;
Note that both function won't exist after I push my series refactoring -device generation. You'll need to use the *Props versions.

On Mon, Oct 11, 2021 at 09:04:43AM +0200, Peter Krempa wrote:
On Fri, Oct 08, 2021 at 18:51:54 +0200, Andrea Bolognani wrote:
case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + if (qemuBuildVirtioDevStr(&opts, "virtio-iommu", qemuCaps, + VIR_DOMAIN_DEVICE_IOMMU, iommu) < 0) { + return -1; + } + + if (qemuBuildDeviceAddressStr(&opts, def, &iommu->info) < 0) + return -1;
Note that both function won't exist after I push my series refactoring -device generation. You'll need to use the *Props versions.
Thanks for the heads up! I'll keep an eye out for your series being merged and send out a rebased version once that happens :) -- Andrea Bolognani / Red Hat / Virtualization

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 a02802a954..9cbc63f6c7 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7948,8 +7948,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 caa61f0646..ab524a68fe 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -32,6 +32,10 @@ v7.9.0 (unreleased) controller. The default behavior is unchanged (hotplug is allowed). + * qemu: Introduce support for virtio-iommu + + This IOMMU device can be used with both Q35 and ARM virt guests. + * **Improvements** * **Bug fixes** -- 2.31.1
participants (2)
-
Andrea Bolognani
-
Peter Krempa