[PATCH 0/6] virtio-iommu: Support setting aw-bits and granule
*** BLURB HERE *** Michal Prívozník (6): qemu_capabilities: Introduce QEMU_CAPS_VIRTIO_IOMMU_AW_BITS conf: Allow aw_bits for virtio-iommu qemu_command: Generate aw_bits prop for virtio-iommu conf: Introduce granule attribute for virtio-iommu qemu_validate: Check whether granule of virtio-iommu is supported qemu_command: Generate granule prop for virtio-iommu docs/formatdomain.rst | 9 +++++- src/conf/domain_conf.c | 30 ++++++++++++++++++- src/conf/domain_conf.h | 13 ++++++++ src/conf/domain_validate.c | 18 +++++++---- src/conf/schemas/domaincommon.rng | 11 +++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 7 +++++ src/qemu/qemu_validate.c | 13 ++++++-- .../caps_10.0.0_aarch64.xml | 1 + .../caps_10.0.0_ppc64.xml | 1 + .../caps_10.0.0_s390x.xml | 1 + .../caps_10.0.0_x86_64+amdsev.xml | 1 + .../caps_10.0.0_x86_64.xml | 1 + .../caps_10.1.0_s390x.xml | 1 + .../caps_10.1.0_x86_64+inteltdx.xml | 1 + .../caps_10.1.0_x86_64.xml | 1 + .../caps_10.2.0_aarch64.xml | 1 + .../caps_10.2.0_x86_64+mshv.xml | 1 + .../caps_10.2.0_x86_64.xml | 1 + .../caps_11.0.0_aarch64.xml | 1 + .../caps_11.0.0_x86_64.xml | 1 + .../caps_9.0.0_x86_64.xml | 1 + .../caps_9.1.0_riscv64.xml | 1 + .../qemucapabilitiesdata/caps_9.1.0_s390x.xml | 1 + .../caps_9.1.0_x86_64.xml | 1 + .../caps_9.2.0_aarch64+hvf.xml | 1 + .../qemucapabilitiesdata/caps_9.2.0_s390x.xml | 1 + .../caps_9.2.0_x86_64+amdsev.xml | 1 + .../caps_9.2.0_x86_64.xml | 1 + .../virtio-iommu-aarch64.aarch64-latest.args | 2 +- .../virtio-iommu-aarch64.aarch64-latest.xml | 1 + .../qemuxmlconfdata/virtio-iommu-aarch64.xml | 4 ++- ...io-iommu-dma-translation.x86_64-latest.err | 2 +- 35 files changed, 124 insertions(+), 12 deletions(-) -- 2.52.0
From: Michal Privoznik <mprivozn@redhat.com> This capability tracks whether the virtio-iommu device has aw-bits attribute. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml | 1 + tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml | 1 + tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_10.1.0_s390x.xml | 1 + tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml | 1 + tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml | 1 + tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml | 1 + tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml | 1 + tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml | 1 + tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml | 1 + tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml | 1 + tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml | 1 + 23 files changed, 24 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index f456e8a378..b4d52eebcd 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -755,6 +755,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "disk-timed-stats", /* QEMU_CAPS_DISK_TIMED_STATS */ "query-accelerators", /* QEMU_CAPS_QUERY_ACCELERATORS */ "mshv", /* QEMU_CAPS_MSHV */ + "virtio-iommu.aw-bits", /* QEMU_CAPS_VIRTIO_IOMMU_AW_BITS */ ); @@ -1612,6 +1613,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVirtioMemPCI[] = static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVirtioIOMMU[] = { { "boot-bypass", QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS, NULL }, + { "aw-bits", QEMU_CAPS_VIRTIO_IOMMU_AW_BITS, NULL }, }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVirtioBlkCCW[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f180844e66..b02385ab0f 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -730,6 +730,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_DISK_TIMED_STATS, /* timed stats support ('stats-intervals' property of disk frontends) */ QEMU_CAPS_QUERY_ACCELERATORS, /* query-accelerators command */ QEMU_CAPS_MSHV, /* -accel mshv */ + QEMU_CAPS_VIRTIO_IOMMU_AW_BITS, /* virtio-iommu.aw-bits */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml index 90e8d868cc..c2bffe88ad 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml @@ -163,6 +163,7 @@ <flag name='nvme-ns'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>10000000</version> <microcodeVersion>61700285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml index 4b3cded2d1..0b9613b921 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.xml @@ -170,6 +170,7 @@ <flag name='nvme'/> <flag name='nvme-ns'/> <flag name='usb-bot'/> + <flag name='virtio-iommu.aw-bits'/> <version>10000000</version> <microcodeVersion>42900285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml index 82a66a6524..410f7c324c 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml @@ -136,6 +136,7 @@ <flag name='nvme'/> <flag name='nvme-ns'/> <flag name='usb-bot'/> + <flag name='virtio-iommu.aw-bits'/> <version>10000000</version> <microcodeVersion>39100285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml index cfce1c963d..a7166aba44 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml @@ -209,6 +209,7 @@ <flag name='amd-iommu'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>10000000</version> <microcodeVersion>43100285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml index f94c8388d6..4177eb06b6 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml @@ -209,6 +209,7 @@ <flag name='amd-iommu.pci-id'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>10000000</version> <microcodeVersion>43100285</microcodeVersion> <package>v10.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_s390x.xml b/tests/qemucapabilitiesdata/caps_10.1.0_s390x.xml index 8d59566cc0..9faa853da2 100644 --- a/tests/qemucapabilitiesdata/caps_10.1.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_10.1.0_s390x.xml @@ -140,6 +140,7 @@ <flag name='nvme-ns'/> <flag name='usb-bot'/> <flag name='qom-list-get'/> + <flag name='virtio-iommu.aw-bits'/> <version>10001000</version> <microcodeVersion>39100286</microcodeVersion> <package>v10.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml index 377541ff53..d5566234a2 100644 --- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml +++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml @@ -192,6 +192,7 @@ <flag name='tdx-guest'/> <flag name='qom-list-get'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>10001000</version> <microcodeVersion>43100286</microcodeVersion> <package>v10.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml index 520a3d8ee8..12d2b262a5 100644 --- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml @@ -214,6 +214,7 @@ <flag name='tdx-guest'/> <flag name='qom-list-get'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>10001000</version> <microcodeVersion>43100286</microcodeVersion> <package>v10.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml index d0c22d2541..7154cdb66c 100644 --- a/tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml @@ -182,6 +182,7 @@ <flag name='acpi-generic-initiator'/> <flag name='disk-timed-stats'/> <flag name='query-accelerators'/> + <flag name='virtio-iommu.aw-bits'/> <version>10002000</version> <microcodeVersion>61700287</microcodeVersion> <package>v10.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml index 2b6708be6a..0d627136e8 100644 --- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml +++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml @@ -202,6 +202,7 @@ <flag name='disk-timed-stats'/> <flag name='query-accelerators'/> <flag name='mshv'/> + <flag name='virtio-iommu.aw-bits'/> <version>10002000</version> <microcodeVersion>43100287</microcodeVersion> <package>v10.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml index 06f7bf784d..5eae704512 100644 --- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml @@ -215,6 +215,7 @@ <flag name='acpi-generic-initiator'/> <flag name='disk-timed-stats'/> <flag name='query-accelerators'/> + <flag name='virtio-iommu.aw-bits'/> <version>10002000</version> <microcodeVersion>43100287</microcodeVersion> <package>v10.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml index f626f3ea46..3600be0301 100644 --- a/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml @@ -182,6 +182,7 @@ <flag name='acpi-generic-initiator'/> <flag name='disk-timed-stats'/> <flag name='query-accelerators'/> + <flag name='virtio-iommu.aw-bits'/> <version>10002050</version> <microcodeVersion>61700286</microcodeVersion> <package>v10.2.0-476-gcf3e71d8fc</package> diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml index f5ef2b2e45..6aa17de843 100644 --- a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml @@ -215,6 +215,7 @@ <flag name='acpi-generic-initiator'/> <flag name='disk-timed-stats'/> <flag name='query-accelerators'/> + <flag name='virtio-iommu.aw-bits'/> <version>10002050</version> <microcodeVersion>43100286</microcodeVersion> <package>v10.2.0-476-gcf3e71d8fc</package> diff --git a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml index 1f2e27a218..43c174e0e6 100644 --- a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml @@ -204,6 +204,7 @@ <flag name='amd-iommu'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>9000000</version> <microcodeVersion>43100245</microcodeVersion> <package>v9.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml b/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml index 85c013a724..b5ca67b445 100644 --- a/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.xml @@ -162,6 +162,7 @@ <flag name='nvme-ns'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>9001000</version> <microcodeVersion>0</microcodeVersion> <package>v9.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml index b961f79808..78b7493b53 100644 --- a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml @@ -126,6 +126,7 @@ <flag name='nvme'/> <flag name='nvme-ns'/> <flag name='usb-bot'/> + <flag name='virtio-iommu.aw-bits'/> <version>9001000</version> <microcodeVersion>39100246</microcodeVersion> <package>v9.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml index 35ddf30736..d68bb783e8 100644 --- a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml @@ -203,6 +203,7 @@ <flag name='amd-iommu'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>9001000</version> <microcodeVersion>43100246</microcodeVersion> <package>v9.1.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml b/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml index 79784d553f..9c843f9e5c 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml @@ -135,6 +135,7 @@ <flag name='nvme-ns'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>9002002</version> <microcodeVersion>61700247</microcodeVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml index e9f79261f7..01fb50038d 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml @@ -129,6 +129,7 @@ <flag name='nvme'/> <flag name='nvme-ns'/> <flag name='usb-bot'/> + <flag name='virtio-iommu.aw-bits'/> <version>9002000</version> <microcodeVersion>39100247</microcodeVersion> <package>v9.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml index 0e52c3e23d..ac936bc17b 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml @@ -207,6 +207,7 @@ <flag name='amd-iommu'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>9002000</version> <microcodeVersion>43100247</microcodeVersion> <package>v9.2.0</package> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml index 95f8a4d878..fd851d9201 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml @@ -205,6 +205,7 @@ <flag name='amd-iommu'/> <flag name='usb-bot'/> <flag name='acpi-generic-initiator'/> + <flag name='virtio-iommu.aw-bits'/> <version>9002000</version> <microcodeVersion>43100247</microcodeVersion> <package>v9.2.0</package> -- 2.52.0
From: Michal Privoznik <mprivozn@redhat.com> Introduced in QEMU commit of v9.0.0-rc0~9^2~7 the virtio-iommu device is also capable of using different addres width. The corresponding attribute is also called 'aw-bits', just like in case of intel-iommu. Wire up the missing pieces. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 2 +- src/conf/domain_validate.c | 9 +++++++-- src/qemu/qemu_validate.c | 7 +++++-- .../virtio-iommu-aarch64.aarch64-latest.xml | 1 + tests/qemuxmlconfdata/virtio-iommu-aarch64.xml | 4 +++- .../virtio-iommu-dma-translation.x86_64-latest.err | 2 +- 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 04ef319a73..4b34a8a963 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9243,7 +9243,7 @@ Example: ``aw_bits`` The ``aw_bits`` attribute can be used to set the address width to allow mapping larger iova addresses in the guest. :since:`Since 6.5.0` (QEMU/KVM - and ``intel`` model only) + and ``intel`` or ``virtio`` models only) ``dma_translation`` The ``dma_translation`` attribute with possible values ``on`` and ``off`` can diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 4482203087..440f23d726 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3206,14 +3206,19 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || - iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0) { virReportError(VIR_ERR_XML_ERROR, - _("iommu model '%1$s' doesn't support additional attributes"), + _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); return -1; } + + if (iommu->aw_bits != 0 && (iommu->aw_bits < 32 || iommu->aw_bits > 64)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("aw-bits must be within [32,64]")); + return -1; + } break; case VIR_DOMAIN_IOMMU_MODEL_AMD: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 184c23d307..ab8a1938c1 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5551,6 +5551,8 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, const virDomainDef *def, virQEMUCaps *qemuCaps) { + bool aw_bits_supported = false; + switch (iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_INTEL: if (!qemuDomainIsQ35(def)) { @@ -5565,6 +5567,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, virDomainIOMMUModelTypeToString(iommu->model)); return -1; } + aw_bits_supported = virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_AW_BITS); break; case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: @@ -5610,6 +5613,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, virDomainIOMMUModelTypeToString(iommu->model)); return -1; } + aw_bits_supported = virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOMMU_AW_BITS); break; case VIR_DOMAIN_IOMMU_MODEL_AMD: @@ -5669,8 +5673,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, _("iommu: device IOTLB is not supported with this QEMU binary")); return -1; } - if (iommu->aw_bits > 0 && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_AW_BITS)) { + if (iommu->aw_bits > 0 && !aw_bits_supported) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("iommu: aw_bits is not supported with this QEMU binary")); return -1; diff --git a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml index 3cb794cbc9..4ae628ab5a 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml +++ b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml @@ -29,6 +29,7 @@ <audio id='1' type='none'/> <memballoon model='none'/> <iommu model='virtio'> + <driver aw_bits='48'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> </iommu> </devices> diff --git a/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml b/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml index 8d252bfcf9..96e5ea05ae 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml +++ b/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml @@ -13,6 +13,8 @@ <emulator>/usr/bin/qemu-system-aarch64</emulator> <controller type='usb' model='none'/> <memballoon model='none'/> - <iommu model='virtio'/> + <iommu model='virtio'> + <driver aw_bits='48'/> + </iommu> </devices> </domain> diff --git a/tests/qemuxmlconfdata/virtio-iommu-dma-translation.x86_64-latest.err b/tests/qemuxmlconfdata/virtio-iommu-dma-translation.x86_64-latest.err index 2c3a272725..f4405a9b7d 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-dma-translation.x86_64-latest.err +++ b/tests/qemuxmlconfdata/virtio-iommu-dma-translation.x86_64-latest.err @@ -1 +1 @@ -XML error: iommu model 'virtio' doesn't support additional attributes +XML error: iommu model 'virtio' doesn't support some additional attributes -- 2.52.0
On Wed, Jan 21, 2026 at 17:27:18 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Introduced in QEMU commit of v9.0.0-rc0~9^2~7 the virtio-iommu device is also capable of using different addres width. The corresponding attribute is also called 'aw-bits', just like in case of intel-iommu. Wire up the missing pieces.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 2 +- src/conf/domain_validate.c | 9 +++++++-- src/qemu/qemu_validate.c | 7 +++++-- .../virtio-iommu-aarch64.aarch64-latest.xml | 1 + tests/qemuxmlconfdata/virtio-iommu-aarch64.xml | 4 +++- .../virtio-iommu-dma-translation.x86_64-latest.err | 2 +- 6 files changed, 18 insertions(+), 7 deletions(-)
[...]
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 4482203087..440f23d726 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3206,14 +3206,19 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || - iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0) { virReportError(VIR_ERR_XML_ERROR, - _("iommu model '%1$s' doesn't support additional attributes"), + _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); return -1; } +
Do you have any justification that you could put into a comment here for the values?
+ if (iommu->aw_bits != 0 && (iommu->aw_bits < 32 || iommu->aw_bits > 64)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("aw-bits must be within [32,64]")); + return -1; + } break;
On 1/21/26 17:57, Peter Krempa wrote:
On Wed, Jan 21, 2026 at 17:27:18 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Introduced in QEMU commit of v9.0.0-rc0~9^2~7 the virtio-iommu device is also capable of using different addres width. The corresponding attribute is also called 'aw-bits', just like in case of intel-iommu. Wire up the missing pieces.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 2 +- src/conf/domain_validate.c | 9 +++++++-- src/qemu/qemu_validate.c | 7 +++++-- .../virtio-iommu-aarch64.aarch64-latest.xml | 1 + tests/qemuxmlconfdata/virtio-iommu-aarch64.xml | 4 +++- .../virtio-iommu-dma-translation.x86_64-latest.err | 2 +- 6 files changed, 18 insertions(+), 7 deletions(-)
[...]
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 4482203087..440f23d726 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3206,14 +3206,19 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || - iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0) { virReportError(VIR_ERR_XML_ERROR, - _("iommu model '%1$s' doesn't support additional attributes"), + _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); return -1; } +
Do you have any justification that you could put into a comment here for the values?
You mean like what values are allowed and which aren't? Michal
On Thu, Jan 22, 2026 at 12:01:03 +0100, Michal Prívozník wrote:
On 1/21/26 17:57, Peter Krempa wrote:
On Wed, Jan 21, 2026 at 17:27:18 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Introduced in QEMU commit of v9.0.0-rc0~9^2~7 the virtio-iommu device is also capable of using different addres width. The corresponding attribute is also called 'aw-bits', just like in case of intel-iommu. Wire up the missing pieces.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 2 +- src/conf/domain_validate.c | 9 +++++++-- src/qemu/qemu_validate.c | 7 +++++-- .../virtio-iommu-aarch64.aarch64-latest.xml | 1 + tests/qemuxmlconfdata/virtio-iommu-aarch64.xml | 4 +++- .../virtio-iommu-dma-translation.x86_64-latest.err | 2 +- 6 files changed, 18 insertions(+), 7 deletions(-)
[...]
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 4482203087..440f23d726 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3206,14 +3206,19 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || - iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0) { virReportError(VIR_ERR_XML_ERROR, - _("iommu model '%1$s' doesn't support additional attributes"), + _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); return -1; } +
Do you have any justification that you could put into a comment here for the values?
You mean like what values are allowed and which aren't?
Sorry I've misplaced my comment. I wanted to know why the range is between 32 and 64 (inclusive), since it's magic constants. If you have some reasoning you could use there please add it as a comment
From: Michal Privoznik <mprivozn@redhat.com> Resolves: https://issues.redhat.com/browse/RHEL-76269 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 1 + tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0de0a79b46..6a01d647b9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6309,6 +6309,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, if (virJSONValueObjectAdd(&props, "s:driver", "virtio-iommu", "s:id", iommu->info.alias, + "z:aw-bits", iommu->aw_bits, NULL) < 0) { return -1; } diff --git a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args index 40b5bf7766..071bc00b34 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args +++ b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args @@ -28,7 +28,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ --device '{"driver":"virtio-iommu","id":"iommu0","bus":"pcie.0","addr":"0x1"}' \ +-device '{"driver":"virtio-iommu","id":"iommu0","aw-bits":48,"bus":"pcie.0","addr":"0x1"}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on -- 2.52.0
On Wed, Jan 21, 2026 at 17:27:19 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Resolves: https://issues.redhat.com/browse/RHEL-76269 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 1 + tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0de0a79b46..6a01d647b9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6309,6 +6309,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, if (virJSONValueObjectAdd(&props, "s:driver", "virtio-iommu", "s:id", iommu->info.alias, + "z:aw-bits", iommu->aw_bits,
struct _virDomainIOMMUDef { virDomainIOMMUModel model; virTristateSwitch intremap; virTristateSwitch caching_mode; virTristateSwitch eim; virTristateSwitch iotlb; unsigned int aw_bits; ^^^^^^^ virJSONValueObjectAddVArgs: * k: signed integer value, omitted if negative * z: signed integer value, omitted if zero ^^^^^^ * y: signed integer value, omitted if zero, error if negative [...] * p: unsigned integer value, omitted if zero
On 1/21/26 18:00, Peter Krempa wrote:
On Wed, Jan 21, 2026 at 17:27:19 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Resolves: https://issues.redhat.com/browse/RHEL-76269 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 1 + tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0de0a79b46..6a01d647b9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6309,6 +6309,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, if (virJSONValueObjectAdd(&props, "s:driver", "virtio-iommu", "s:id", iommu->info.alias, + "z:aw-bits", iommu->aw_bits,
struct _virDomainIOMMUDef { virDomainIOMMUModel model; virTristateSwitch intremap; virTristateSwitch caching_mode; virTristateSwitch eim; virTristateSwitch iotlb; unsigned int aw_bits;
^^^^^^^
virJSONValueObjectAddVArgs:
* k: signed integer value, omitted if negative * z: signed integer value, omitted if zero
^^^^^^
* y: signed integer value, omitted if zero, error if negative
[...]
* p: unsigned integer value, omitted if zero
Darn. I've just copied the line over from intel case. Let me post a fix for that one first. Nice catch! Michal
From: Michal Privoznik <mprivozn@redhat.com> In PCI assignment scenario the virtio-iommu needs to know the guest page size also known as granule. Expose it as an attribute to the <driver/> element of a virtio-iommu. This is possibly interesting only for aarch64 since it supports virtio-iommu and also supports running guests with different page size than the host. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 7 +++++ src/conf/domain_conf.c | 30 ++++++++++++++++++- src/conf/domain_conf.h | 13 ++++++++ src/conf/domain_validate.c | 9 ++++-- src/conf/schemas/domaincommon.rng | 11 +++++++ src/libvirt_private.syms | 2 ++ .../virtio-iommu-aarch64.aarch64-latest.xml | 2 +- .../qemuxmlconfdata/virtio-iommu-aarch64.xml | 2 +- 8 files changed, 70 insertions(+), 6 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 4b34a8a963..1dfe3915b5 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9264,6 +9264,13 @@ Example: The ``pciBus`` attribute notes the index of the controller that an IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only) + ``granule`` + This allows to choose which granule will be used by default by the + virtio-iommu and is useful when running guests with different page size + than the host. Accepted values are: ``4K``, ``8K``, ``16K``, ``64K`` and + ``host`` (matches the host page size). :since:`Since 12.1.0` (QEMU/KVM + and ``virtio`` model only). + The ``virtio`` IOMMU devices can further have ``address`` element as described in `Device addresses`_ (address has to by type of ``pci``). diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d00a43e969..140333b1ec 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1356,6 +1356,16 @@ VIR_ENUM_IMPL(virDomainIOMMUModel, "amd", ); +VIR_ENUM_IMPL(virDomainIOMMUGranuleMode, + VIR_DOMAIN_IOMMU_GRANULE_MODE_LAST, + "none", + "4K", + "8K", + "16K", + "64K", + "host", +); + VIR_ENUM_IMPL(virDomainVsockModel, VIR_DOMAIN_VSOCK_MODEL_LAST, "default", @@ -14514,6 +14524,12 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, if (virXMLPropInt(driver, "pciBus", 10, VIR_XML_PROP_NONE, &iommu->pci_bus, -1) < 0) return NULL; + + if (virXMLPropEnum(driver, "granule", + virDomainIOMMUGranuleModeTypeFromString, + VIR_XML_PROP_NONZERO, &iommu->granule_mode) < 0) { + return NULL; + } } if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, @@ -16565,7 +16581,8 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, a->eim != b->eim || a->iotlb != b->iotlb || a->aw_bits != b->aw_bits || - a->dma_translation != b->dma_translation) + a->dma_translation != b->dma_translation || + a->granule_mode != b->granule_mode) return false; if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && @@ -22320,6 +22337,13 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, virTristateSwitchTypeToString(src->xtsup)); return false; } + if (src->granule_mode != dst->granule_mode) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device granule '%1$s' does not match source '%2$s'"), + virDomainIOMMUGranuleModeTypeToString(dst->granule_mode), + virDomainIOMMUGranuleModeTypeToString(src->granule_mode)); + return false; + } return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); } @@ -28645,6 +28669,10 @@ virDomainIOMMUDefFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " pciBus='%d'", iommu->pci_bus); } + if (iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { + virBufferAsprintf(&driverAttrBuf, " granule='%s'", + virDomainIOMMUGranuleModeTypeToString(iommu->granule_mode)); + } virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 83d49969d3..8ea620a738 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3050,6 +3050,17 @@ typedef enum { VIR_DOMAIN_IOMMU_MODEL_LAST } virDomainIOMMUModel; +typedef enum { + VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE = 0, + VIR_DOMAIN_IOMMU_GRANULE_MODE_4K, + VIR_DOMAIN_IOMMU_GRANULE_MODE_8K, + VIR_DOMAIN_IOMMU_GRANULE_MODE_16K, + VIR_DOMAIN_IOMMU_GRANULE_MODE_64K, + VIR_DOMAIN_IOMMU_GRANULE_MODE_HOST, + + VIR_DOMAIN_IOMMU_GRANULE_MODE_LAST +} virDomainIOMMUGranuleMode; + struct _virDomainIOMMUDef { virDomainIOMMUModel model; virTristateSwitch intremap; @@ -3062,6 +3073,7 @@ struct _virDomainIOMMUDef { virTristateSwitch dma_translation; virTristateSwitch xtsup; virTristateSwitch pt; + virDomainIOMMUGranuleMode granule_mode; }; typedef enum { @@ -4443,6 +4455,7 @@ VIR_ENUM_DECL(virDomainMemoryBackingModel); VIR_ENUM_DECL(virDomainMemorySource); VIR_ENUM_DECL(virDomainMemoryAllocation); VIR_ENUM_DECL(virDomainIOMMUModel); +VIR_ENUM_DECL(virDomainIOMMUGranuleMode); VIR_ENUM_DECL(virDomainVsockModel); VIR_ENUM_DECL(virDomainCryptoModel); VIR_ENUM_DECL(virDomainCryptoType); diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 440f23d726..fd28526159 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3194,7 +3194,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || - iommu->pt != VIR_TRISTATE_SWITCH_ABSENT) { + iommu->pt != VIR_TRISTATE_SWITCH_ABSENT || + iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); @@ -3226,7 +3227,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || - iommu->pci_bus >= 0) { + iommu->pci_bus >= 0 || + iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); @@ -3237,7 +3239,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) case VIR_DOMAIN_IOMMU_MODEL_INTEL: if (iommu->pt != VIR_TRISTATE_SWITCH_ABSENT || iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || - iommu->pci_bus >= 0) { + iommu->pci_bus >= 0 || + iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 114dd3f96f..175e735a99 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6329,6 +6329,17 @@ <data type="unsignedInt"/> </attribute> </optional> + <optional> + <attribute name="granule"> + <choice> + <value>4K</value> + <value>8K</value> + <value>16K</value> + <value>64K</value> + <value>host</value> + </choice> + </attribute> + </optional> </element> </optional> <optional> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6bffd2eb6d..d34b65a415 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -499,6 +499,8 @@ virDomainIOMMUDefEquals; virDomainIOMMUDefFind; virDomainIOMMUDefFree; virDomainIOMMUDefNew; +virDomainIOMMUGranuleModeTypeFromString; +virDomainIOMMUGranuleModeTypeToString; virDomainIOMMUModelTypeFromString; virDomainIOMMUModelTypeToString; virDomainIOThreadIDAdd; diff --git a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml index 4ae628ab5a..709a24f796 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml +++ b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml @@ -29,7 +29,7 @@ <audio id='1' type='none'/> <memballoon model='none'/> <iommu model='virtio'> - <driver aw_bits='48'/> + <driver aw_bits='48' granule='64K'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> </iommu> </devices> diff --git a/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml b/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml index 96e5ea05ae..bf8bc58211 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml +++ b/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml @@ -14,7 +14,7 @@ <controller type='usb' model='none'/> <memballoon model='none'/> <iommu model='virtio'> - <driver aw_bits='48'/> + <driver aw_bits='48' granule='64K'/> </iommu> </devices> </domain> -- 2.52.0
On Wed, Jan 21, 2026 at 17:27:20 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
In PCI assignment scenario the virtio-iommu needs to know the guest page size also known as granule. Expose it as an attribute
^^^^
to the <driver/> element of a virtio-iommu.
This is possibly interesting only for aarch64 since it supports virtio-iommu and also supports running guests with different page size than the host.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 7 +++++ src/conf/domain_conf.c | 30 ++++++++++++++++++- src/conf/domain_conf.h | 13 ++++++++ src/conf/domain_validate.c | 9 ++++-- src/conf/schemas/domaincommon.rng | 11 +++++++ src/libvirt_private.syms | 2 ++ .../virtio-iommu-aarch64.aarch64-latest.xml | 2 +- .../qemuxmlconfdata/virtio-iommu-aarch64.xml | 2 +- 8 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 4b34a8a963..1dfe3915b5 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9264,6 +9264,13 @@ Example: The ``pciBus`` attribute notes the index of the controller that an IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only)
+ ``granule`` + This allows to choose which granule will be used by default by the
Put the above explanation also here.
+ virtio-iommu and is useful when running guests with different page size + than the host. Accepted values are: ``4K``, ``8K``, ``16K``, ``64K`` and
Since this is supposed to mean page size you should use the lowercase 'k' for kilo? Or perhaps directly kiB ?
+ ``host`` (matches the host page size). :since:`Since 12.1.0` (QEMU/KVM + and ``virtio`` model only). + The ``virtio`` IOMMU devices can further have ``address`` element as described in `Device addresses`_ (address has to by type of ``pci``).
On 1/21/26 18:04, Peter Krempa wrote:
On Wed, Jan 21, 2026 at 17:27:20 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
In PCI assignment scenario the virtio-iommu needs to know the guest page size also known as granule. Expose it as an attribute
^^^^
to the <driver/> element of a virtio-iommu.
This is possibly interesting only for aarch64 since it supports virtio-iommu and also supports running guests with different page size than the host.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 7 +++++ src/conf/domain_conf.c | 30 ++++++++++++++++++- src/conf/domain_conf.h | 13 ++++++++ src/conf/domain_validate.c | 9 ++++-- src/conf/schemas/domaincommon.rng | 11 +++++++ src/libvirt_private.syms | 2 ++ .../virtio-iommu-aarch64.aarch64-latest.xml | 2 +- .../qemuxmlconfdata/virtio-iommu-aarch64.xml | 2 +- 8 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 4b34a8a963..1dfe3915b5 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9264,6 +9264,13 @@ Example: The ``pciBus`` attribute notes the index of the controller that an IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only)
+ ``granule`` + This allows to choose which granule will be used by default by the
Put the above explanation also here.
+ virtio-iommu and is useful when running guests with different page size + than the host. Accepted values are: ``4K``, ``8K``, ``16K``, ``64K`` and
Since this is supposed to mean page size you should use the lowercase 'k' for kilo? Or perhaps directly kiB ?
I wondered about that. But let's enumerate our possibilities. 1) <driver granule='4k'/> 2) <driver granule='4096'/> 3) <driver granule='4' unit='KiB'/> 4) <driver granule='4' granuleUnit='KiB'/> 5) <driver> <granule unit='KiB'>4</granule> </driver> Problem with 3 is that 'unit' is not specific enough and if we ever want to invent a new attribute that'd accept units, we're cooked. 4) is more descriptive but I'm not a big fan of it either. That leaves us with 2) where the unit is bytes, or 5) which is the most future proof IMO. Michal
On Thu, Jan 22, 2026 at 12:00:55 +0100, Michal Prívozník wrote:
On 1/21/26 18:04, Peter Krempa wrote:
On Wed, Jan 21, 2026 at 17:27:20 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
In PCI assignment scenario the virtio-iommu needs to know the guest page size also known as granule. Expose it as an attribute
^^^^
to the <driver/> element of a virtio-iommu.
This is possibly interesting only for aarch64 since it supports virtio-iommu and also supports running guests with different page size than the host.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 7 +++++ src/conf/domain_conf.c | 30 ++++++++++++++++++- src/conf/domain_conf.h | 13 ++++++++ src/conf/domain_validate.c | 9 ++++-- src/conf/schemas/domaincommon.rng | 11 +++++++ src/libvirt_private.syms | 2 ++ .../virtio-iommu-aarch64.aarch64-latest.xml | 2 +- .../qemuxmlconfdata/virtio-iommu-aarch64.xml | 2 +- 8 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 4b34a8a963..1dfe3915b5 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9264,6 +9264,13 @@ Example: The ``pciBus`` attribute notes the index of the controller that an IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only)
+ ``granule`` + This allows to choose which granule will be used by default by the
Put the above explanation also here.
+ virtio-iommu and is useful when running guests with different page size + than the host. Accepted values are: ``4K``, ``8K``, ``16K``, ``64K`` and
Since this is supposed to mean page size you should use the lowercase 'k' for kilo? Or perhaps directly kiB ?
I wondered about that. But let's enumerate our possibilities.
1) <driver granule='4k'/> 2) <driver granule='4096'/> 3) <driver granule='4' unit='KiB'/> 4) <driver granule='4' granuleUnit='KiB'/> 5) <driver> <granule unit='KiB'>4</granule> </driver>
Problem with 3 is that 'unit' is not specific enough and if we ever want to invent a new attribute that'd accept units, we're cooked. 4) is more descriptive but I'm not a big fan of it either. That leaves us with 2) where the unit is bytes, or 5) which is the most future proof IMO.
I'm not a fan of the value being content and unit being attribute. You also need to be able to use the 'host' mode which doesn't represent well as a number. Internally we can do 'host' as an extra bool, but also we don't really need to be able (for now) represent the full scale of numbers, but that can be handled by validation. I'd consider: <driver> <granule mode='host'/> or <granule size='4' unit='KiB'/> </driver>
From: Michal Privoznik <mprivozn@redhat.com> Just like with other features, check whether QEMU supports them based on capabilities. Now, instead of inventing a new QEMU capability, an existing one can be used: QEMU_CAPS_VIRTIO_IOMMU_AW_BITS. This is because the aw-bits and granule attributes were introduced into QEMU in close succession (v9.0.0-rc0~9^2~7 v9.0.0-rc0~9^2~11), neither can be disabled at compile time and backporting just one without the other makes almost no sense. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_validate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index ab8a1938c1..f5072941c5 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5684,6 +5684,12 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, _("iommu: updating dma translation is not supported with this QEMU binary")); return -1; } + if (iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOMMU_AW_BITS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: page granule is not supported with this QEMU binary")); + return -1; + } return 0; } -- 2.52.0
On Wed, Jan 21, 2026 at 17:27:21 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Just like with other features, check whether QEMU supports them based on capabilities. Now, instead of inventing a new QEMU capability, an existing one can be used: QEMU_CAPS_VIRTIO_IOMMU_AW_BITS.
This is because the aw-bits and granule attributes were introduced into QEMU in close succession (v9.0.0-rc0~9^2~7 v9.0.0-rc0~9^2~11), neither can be disabled at compile time and backporting just one without the other makes almost no sense.
A similar justification, possibly a bit more condensed ...
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_validate.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index ab8a1938c1..f5072941c5 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5684,6 +5684,12 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, _("iommu: updating dma translation is not supported with this QEMU binary")); return -1; }
... needs to be put into a comment somewhere here.
+ if (iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOMMU_AW_BITS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: page granule is not supported with this QEMU binary")); + return -1; + }
return 0; } -- 2.52.0
From: Michal Privoznik <mprivozn@redhat.com> Resolves: https://issues.redhat.com/browse/RHEL-76269 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 6 ++++++ .../virtio-iommu-aarch64.aarch64-latest.args | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6a01d647b9..0fde2eb659 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6285,6 +6285,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, virDomainIOMMUDef *iommu = def->iommus[i]; g_autoptr(virJSONValue) props = NULL; g_autoptr(virJSONValue) wrapperProps = NULL; + const char *granule_mode = NULL; switch (iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_INTEL: @@ -6306,10 +6307,15 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, break; case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + if (iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { + granule_mode = virDomainIOMMUGranuleModeTypeToString(iommu->granule_mode); + } + if (virJSONValueObjectAdd(&props, "s:driver", "virtio-iommu", "s:id", iommu->info.alias, "z:aw-bits", iommu->aw_bits, + "S:granule", granule_mode, NULL) < 0) { return -1; } diff --git a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args index 071bc00b34..85160f3ca4 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args +++ b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.args @@ -28,7 +28,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ --device '{"driver":"virtio-iommu","id":"iommu0","aw-bits":48,"bus":"pcie.0","addr":"0x1"}' \ +-device '{"driver":"virtio-iommu","id":"iommu0","aw-bits":48,"granule":"64K","bus":"pcie.0","addr":"0x1"}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on -- 2.52.0
On Wed, Jan 21, 2026 at 17:27:22 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Resolves: https://issues.redhat.com/browse/RHEL-76269 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 6 ++++++ .../virtio-iommu-aarch64.aarch64-latest.args | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6a01d647b9..0fde2eb659 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6285,6 +6285,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, virDomainIOMMUDef *iommu = def->iommus[i]; g_autoptr(virJSONValue) props = NULL; g_autoptr(virJSONValue) wrapperProps = NULL; + const char *granule_mode = NULL;
switch (iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_INTEL: @@ -6306,10 +6307,15 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, break;
case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + if (iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { + granule_mode = virDomainIOMMUGranuleModeTypeToString(iommu->granule_mode); + } + if (virJSONValueObjectAdd(&props, "s:driver", "virtio-iommu", "s:id", iommu->info.alias, "z:aw-bits", iommu->aw_bits, + "S:granule", granule_mode,
okay so you are doing a 1:1 mapping to qemu values, but I still wonder what the intention behind the specific values is. If it's supposed to mean the number we IMO should use proper unit. (which will require a different enum convertor for use here).
On Wed, Jan 21, 2026 at 17:27:16 +0100, Michal Privoznik via Devel wrote:
*** BLURB HERE ***
Michal Prívozník (6): qemu_capabilities: Introduce QEMU_CAPS_VIRTIO_IOMMU_AW_BITS conf: Allow aw_bits for virtio-iommu qemu_command: Generate aw_bits prop for virtio-iommu conf: Introduce granule attribute for virtio-iommu qemu_validate: Check whether granule of virtio-iommu is supported qemu_command: Generate granule prop for virtio-iommu
Looks good except for the naming of the 'granule' values, which we should discuss in the patch. Reviewed-by: Peter Krempa <pkrempa@redhat.com>
participants (3)
-
Michal Privoznik -
Michal Prívozník -
Peter Krempa