[PATCH v7 0/2] qemu: Support accelerated vSMMUs
Hi, This is a follow up to the sixth RFC patchset [0] for supporting multiple accelerated vSMMU instances. Support for user-creatable accelerated SMMUv3 in QEMU has been applied to target-arm.next [1]. For instance, specifying hostdevs associated with multiple accelerated SMMUs, configured to be routed to pcie-expander-bus controllers in a way where VFIO device to SMMUv3 associations are matched with the host: <devices> ... <controller type='pci' index='1' model='pcie-expander-bus'> <model name='pxb-pcie'/> <target busNr='252'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> </controller> <controller type='pci' index='2' model='pcie-expander-bus'> <model name='pxb-pcie'/> <target busNr='248'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </controller> ... <controller type='pci' index='21' model='pcie-root-port'> <model name='pcie-root-port'/> <target chassis='21' port='0x0'/> <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </controller> <controller type='pci' index='22' model='pcie-root-port'> <model name='pcie-root-port'/> <target chassis='22' port='0xa8'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> </controller> ... <hostdev mode='subsystem' type='pci' managed='no'> <source> <address domain='0x0009' bus='0x01' slot='0x00' function='0x0'/> </source> <vpasidCapOffset>0xff8</vpasidCapOffset> <address type='pci' domain='0x0000' bus='0x15' slot='0x00' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='no'> <source> <address domain='0x0019' bus='0x01' slot='0x00' function='0x0'/> </source> <vpasidCapOffset>0xff8</vpasidCapOffset> <address type='pci' domain='0x0000' bus='0x16' slot='0x00' function='0x0'/> </hostdev> <iommu model='smmuv3'> <driver parentIdx='1' accel='on' ats='on' ril='off' ssidSize='20' oas='44'/> </iommu> <iommu model='smmuv3'> <driver parentIdx='2' accel='on' ats='on' ril='off' ssidSize='20' oas='44'/> </iommu> </devices> This would get translated to a qemu command line with the arguments below: -device '{"driver":"pxb-pcie","bus_nr":252,"id":"pci.1","bus":"pcie.0","addr":"0x1"}' \ -device '{"driver":"pxb-pcie","bus_nr":248,"id":"pci.2","bus":"pcie.0","addr":"0x2"}' \ -device '{"driver":"pcie-root-port","port":0,"chassis":21,"id":"pci.21","bus":"pci.1","addr":"0x0"}' \ -device '{"driver":"pcie-root-port","port":168,"chassis":22,"id":"pci.22","bus":"pci.2","addr":"0x0"}' \ -device '{"driver":"arm-smmuv3","primary-bus":"pci.1","id":"iommu0","accel":true,"ats":true,"ril":false,"ssidsize":20,"oas":44}' \ -device '{"driver":"arm-smmuv3","primary-bus":"pci.2","id":"iommu1","accel":true,"ats":true,"ril":false,"ssidsize":20,"oas":44}' \ -device '{"driver":"vfio-pci","host":"0009:01:00.0","id":"hostdev0","x-vpasid-cap-offset":4088,"bus":"pci.21","addr":"0x0"}' \ -device '{"driver":"vfio-pci","host":"0019:01:00.0","id":"hostdev1","x-vpasid-cap-offset":4088,"bus":"pci.22","addr":"0x0"}' \ This series is on Github: https://github.com/NathanChenNVIDIA/libvirt/tree/smmuv3-accel-01-26-v7/ Thanks, Nathan Changes from v6: - Remove smmuv3 'pasid' attribute - Add smmuv3 'ssidsize' attribute - Add support for 'vpasidCapOffset' element - Modify logic for building accel smmuv3 qemu command line to omit ATS, RIL, accel flags when not needed (enabled/disabled by default in QEMU SMMUv3) [0] https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/VRSSX... [1] https://lore.kernel.org/qemu-devel/20260126104342.253965-1-skolothumtho@nvid... Nathan Chen (2): qemu: Add support for HW-accelerated nested SMMUv3 tests: qemuxmlconfdata: provide HW-accel smmuv3 sample XML and CLI args docs/formatdomain.rst | 36 +++++++ src/conf/domain_conf.c | 101 +++++++++++++++++- src/conf/domain_conf.h | 6 ++ src/conf/domain_validate.c | 36 ++++++- src/conf/schemas/domaincommon.rng | 32 ++++++ src/qemu/qemu_command.c | 23 ++++ src/util/virpci.h | 4 + ...u-smmuv3-pci-bus-accel.aarch64-latest.args | 38 +++++++ ...mu-smmuv3-pci-bus-accel.aarch64-latest.xml | 64 +++++++++++ .../iommu-smmuv3-pci-bus-accel.xml | 54 ++++++++++ tests/qemuxmlconftest.c | 1 + 11 files changed, 390 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.args create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.xml create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.xml -- 2.43.0
From: Nathan Chen <nathanc@nvidia.com> Add support for enabling HW-accelerated nested SMMUv3 via <accel> attribute and its additional attributes for ATS, SSID, RIL, and OAS configuration. Support element for specifying PCI hostdev PASID capability offset. Signed-off-by: Nathan Chen <nathanc@nvidia.com> --- docs/formatdomain.rst | 36 +++++++++++ src/conf/domain_conf.c | 101 +++++++++++++++++++++++++++++- src/conf/domain_conf.h | 6 ++ src/conf/domain_validate.c | 36 ++++++++++- src/conf/schemas/domaincommon.rng | 32 ++++++++++ src/qemu/qemu_command.c | 23 +++++++ src/util/virpci.h | 4 ++ 7 files changed, 233 insertions(+), 5 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 04ef319a73..998d289ebf 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -4880,6 +4880,13 @@ or: device; if PCI ROM loading is disabled through this attribute, attempts to tweak the loading process further using the ``bar`` or ``file`` attributes will be rejected. :since:`Since 4.3.0 (QEMU and KVM only)`. +``vpasidCapOffset`` + The ``vpasidCapOffset`` element is used to change the offset at which a + PASID PCIe extended capability is placed in a vfio-pci device's PCIe + extended configuration space. If not specified or set to 0, the capability + is placed at the end of the extended configuration space when PASID is + supported. The offset must be 4-byte aligned and within the PCIe extended + configuration space. ``address`` The ``address`` element for USB devices has a ``bus`` and ``device`` attribute to specify the USB bus and device number the device appears at on @@ -9264,6 +9271,35 @@ Example: The ``pciBus`` attribute notes the index of the controller that an IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only) + ``accel`` + The ``accel`` attribute with possible values ``on`` and ``off`` can be used + to enable hardware acceleration support for smmuv3Dev IOMMU devices. + (QEMU/KVM and ``smmuv3`` model only) + + ``ats`` + The ``ats`` attribute with possible values ``on`` and ``off`` can be used + to enable reporting Address Translation Services capability to the guest + for smmuv3Dev IOMMU devices with ``accel`` set to ``on``, if the host + SMMUv3 supports ATS and the associated passthrough device supports ATS. + (QEMU/KVM and ``smmuv3`` model only) + + ``ril`` + The ``ril`` attribute with possible values ``on`` and ``off`` can be used + to report whether Range Invalidation for smmuv3Dev IOMMU devices with + ``accel`` set to ``on`` is compatible with host SMMUv3 support. + (QEMU/KVM and ``smmuv3`` model only) + + ``ssidSize`` + The ``ssidSize`` attribute sets the number of bits used to represent + SubstreamIDs. A value of N allows SSIDs in the range [0 .. 2^N - 1]. + The valid range is 0-20, and a value greater than 0 is required for + enabling PASID support, as doing so advertises PASID capability to + the vIOMMU. (QEMU/KVM and ``smmuv3`` model only) + + ``oas`` + The ``oas`` attribute sets the output address size in units of bits. + (QEMU/KVM and ``smmuv3`` 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 9672168df9..e64484a60d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13678,6 +13678,7 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt, virDomainHostdevDef *def; VIR_XPATH_NODE_AUTORESTORE(ctxt) unsigned int type; + int rc; ctxt->node = node; @@ -13731,8 +13732,16 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt, def->shareable = true; break; - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + rc = virXPathUIntBase("string(./vpasidCapOffset)", ctxt, + 0, &def->vpasidCapOffset); + if (rc == -2) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Invalid format for vpasidCapOffset")); + goto error; + } + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: @@ -14514,6 +14523,26 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, if (virXMLPropInt(driver, "pciBus", 10, VIR_XML_PROP_NONE, &iommu->pci_bus, -1) < 0) return NULL; + + if (virXMLPropTristateSwitch(driver, "accel", VIR_XML_PROP_NONE, + &iommu->accel) < 0) + return NULL; + + if (virXMLPropTristateSwitch(driver, "ats", VIR_XML_PROP_NONE, + &iommu->ats) < 0) + return NULL; + + if (virXMLPropTristateSwitch(driver, "ril", VIR_XML_PROP_NONE, + &iommu->ril) < 0) + return NULL; + + if (virXMLPropUInt(driver, "ssidSize", 10, VIR_XML_PROP_NONE, + &iommu->ssid_size) < 0) + return NULL; + + if (virXMLPropUInt(driver, "oas", 10, VIR_XML_PROP_NONE, + &iommu->oas) < 0) + return NULL; } if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, @@ -16577,7 +16606,13 @@ 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->pci_bus != b->pci_bus || + a->accel != b->accel || + a->ats != b->ats || + a->ril != b->ril || + a->ssid_size != b->ssid_size || + a->oas != b->oas) return false; if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && @@ -21349,6 +21384,14 @@ virDomainHostdevDefCheckABIStability(virDomainHostdevDef *src, } } + if (src->vpasidCapOffset != dst->vpasidCapOffset) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target host device vPASID capability offset %1$s does not match source %2$s"), + virDomainHostdevModeTypeToString(dst->vpasidCapOffset), + virDomainHostdevModeTypeToString(src->vpasidCapOffset)); + return false; + } + if (!virDomainDeviceInfoCheckABIStability(src->info, dst->info)) return false; @@ -22311,6 +22354,36 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, dst->pci_bus, src->pci_bus); return false; } + if (src->accel != dst->accel) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device accel value '%1$d' does not match source '%2$d'"), + dst->accel, src->accel); + return false; + } + if (src->ats != dst->ats) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device ATS value '%1$d' does not match source '%2$d'"), + dst->ats, src->ats); + return false; + } + if (src->ril != dst->ril) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device ril value '%1$d' does not match source '%2$d'"), + dst->ril, src->ril); + return false; + } + if (src->ssid_size != dst->ssid_size) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device ssid_size value '%1$d' does not match source '%2$d'"), + dst->ssid_size, src->ssid_size); + return false; + } + if (src->oas != dst->oas) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device oas value '%1$d' does not match source '%2$d'"), + dst->oas, src->oas); + return false; + } if (src->dma_translation != dst->dma_translation) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain IOMMU device dma translation '%1$s' does not match source '%2$s'"), @@ -27732,6 +27805,10 @@ virDomainHostdevDefFormat(virBuffer *buf, if (def->shareable) virBufferAddLit(buf, "<shareable/>\n"); + if (def->vpasidCapOffset) + virBufferAsprintf(buf, "<vpasidCapOffset>0x%x</vpasidCapOffset>\n", + def->vpasidCapOffset); + virDomainDeviceInfoFormat(buf, def->info, flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT | VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM); @@ -28657,6 +28734,26 @@ virDomainIOMMUDefFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " pciBus='%d'", iommu->pci_bus); } + if (iommu->accel != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&driverAttrBuf, " accel='%s'", + virTristateSwitchTypeToString(iommu->accel)); + } + if (iommu->ats != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&driverAttrBuf, " ats='%s'", + virTristateSwitchTypeToString(iommu->ats)); + } + if (iommu->ril != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&driverAttrBuf, " ril='%s'", + virTristateSwitchTypeToString(iommu->ril)); + } + if (iommu->ssid_size > 0) { + virBufferAsprintf(&driverAttrBuf, " ssidSize='%d'", + iommu->ssid_size); + } + if (iommu->oas > 0) { + virBufferAsprintf(&driverAttrBuf, " oas='%d'", + iommu->oas); + } virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 83d49969d3..1396073678 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -370,6 +370,7 @@ struct _virDomainHostdevDef { bool missing; bool readonly; bool shareable; + unsigned int vpasidCapOffset; virTristateBool writeFiltering; union { virDomainHostdevSubsys subsys; @@ -3062,6 +3063,11 @@ struct _virDomainIOMMUDef { virTristateSwitch dma_translation; virTristateSwitch xtsup; virTristateSwitch pt; + virTristateSwitch accel; + virTristateSwitch ats; + virTristateSwitch ril; + unsigned int ssid_size; + unsigned int oas; }; typedef enum { diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 4482203087..7b2c32395d 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -29,6 +29,7 @@ #include "virutil.h" #include "virstring.h" #include "virhostmem.h" +#include "virpci.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN @@ -2432,6 +2433,20 @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev) _("PCI host devices must use 'pci' or 'unassigned' address type")); return -1; } + if (hostdev->vpasidCapOffset) { + if (hostdev->vpasidCapOffset & 0x3) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("vpasidCapOffset must be 4-byte aligned")); + return -1; + } + /* PASID ECAP size of 0x8 */ + if (hostdev->vpasidCapOffset < VIR_DOMAIN_PCI_CONFIG_SPACE_SIZE || + hostdev->vpasidCapOffset > VIR_DOMAIN_PCIE_CONFIG_SPACE_SIZE - 0x8) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("vpasidCapOffset must be within PCIe extended configuration space (0x100-0xFFF)")); + return -1; + } + } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: if (hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && @@ -3208,7 +3223,12 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || - iommu->pci_bus >= 0) { + iommu->pci_bus >= 0 || + iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ssid_size != 0 || + iommu->oas != 0) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); @@ -3221,7 +3241,12 @@ 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->accel != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ssid_size != 0 || + iommu->oas != 0) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); @@ -3232,7 +3257,12 @@ 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->accel != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ssid_size != 0 || + iommu->oas != 0) { 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..234aae5459 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6329,6 +6329,31 @@ <data type="unsignedInt"/> </attribute> </optional> + <optional> + <attribute name="accel"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="ats"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="ril"> + <ref name="virOnOff"/> + </attribute> + </optional> + <optional> + <attribute name="ssidSize"> + <data type="unsignedInt"/> + </attribute> + </optional> + <optional> + <attribute name="oas"> + <data type="unsignedInt"/> + </attribute> + </optional> </element> </optional> <optional> @@ -6610,6 +6635,13 @@ <ref name="pciaddress"/> </element> </element> + <optional> + <element name="vpasidCapOffset"> + <data type="string"> + <param name="pattern">(0x[0-9a-fA-F]+|[0-9]+)</param> + </data> + </element> + </optional> <ref name="hostdevsubsysvfiodisplay"/> </interleave> </define> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index e81efdfde7..aa5ee2a787 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4802,6 +4802,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, "S:failover_pair_id", failover_pair_id, "S:display", qemuOnOffAuto(pcisrc->display), "B:ramfb", ramfb, + "p:x-vpasid-cap-offset", dev->vpasidCapOffset, NULL) < 0) return NULL; @@ -6267,9 +6268,31 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def, "s:driver", "arm-smmuv3", "s:primary-bus", bus, "s:id", iommu->info.alias, + "B:accel", (iommu->accel == VIR_TRISTATE_SWITCH_ON), + "B:ats", (iommu->ats == VIR_TRISTATE_SWITCH_ON), NULL) < 0) return NULL; + /* QEMU SMMUv3 has RIL support by default; only emit when explicitly disabling */ + if (iommu->ril == VIR_TRISTATE_SWITCH_OFF) { + if (virJSONValueObjectAppendBoolean(props, "ril", false) < 0) + return NULL; + } + + if (iommu->ssid_size > 0) { + if (virJSONValueObjectAdd(&props, + "p:ssidsize", iommu->ssid_size, + NULL) < 0) + return NULL; + } + + if (iommu->oas > 0) { + if (virJSONValueObjectAdd(&props, + "p:oas", iommu->oas, + NULL) < 0) + return NULL; + } + return g_steal_pointer(&props); } diff --git a/src/util/virpci.h b/src/util/virpci.h index fc538566e1..7e78cb267c 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -35,6 +35,10 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceList, virObjectUnref); #define VIR_DOMAIN_DEVICE_ZPCI_MAX_UID UINT16_MAX #define VIR_DOMAIN_DEVICE_ZPCI_MAX_FID UINT32_MAX +/* Size of the standard PCI config space */ +#define VIR_DOMAIN_PCI_CONFIG_SPACE_SIZE 0x100 +/* Size of the standard PCIe config space: 4KB */ +#define VIR_DOMAIN_PCIE_CONFIG_SPACE_SIZE 0x1000 typedef struct _virZPCIDeviceAddressID virZPCIDeviceAddressID; typedef struct _virZPCIDeviceAddress virZPCIDeviceAddress; -- 2.43.0
On Fri, Jan 30, 2026 at 10:37:06AM -0800, Nathan Chen via Devel wrote:
From: Nathan Chen <nathanc@nvidia.com>
Add support for enabling HW-accelerated nested SMMUv3 via <accel> attribute and its additional attributes for ATS, SSID, RIL, and OAS configuration. Support element for specifying PCI hostdev PASID capability offset.
Signed-off-by: Nathan Chen <nathanc@nvidia.com> --- docs/formatdomain.rst | 36 +++++++++++ src/conf/domain_conf.c | 101 +++++++++++++++++++++++++++++- src/conf/domain_conf.h | 6 ++ src/conf/domain_validate.c | 36 ++++++++++- src/conf/schemas/domaincommon.rng | 32 ++++++++++ src/qemu/qemu_command.c | 23 +++++++ src/util/virpci.h | 4 ++ 7 files changed, 233 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 04ef319a73..998d289ebf 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -4880,6 +4880,13 @@ or: device; if PCI ROM loading is disabled through this attribute, attempts to tweak the loading process further using the ``bar`` or ``file`` attributes will be rejected. :since:`Since 4.3.0 (QEMU and KVM only)`. +``vpasidCapOffset`` + The ``vpasidCapOffset`` element is used to change the offset at which a + PASID PCIe extended capability is placed in a vfio-pci device's PCIe + extended configuration space. If not specified or set to 0, the capability + is placed at the end of the extended configuration space when PASID is + supported. The offset must be 4-byte aligned and within the PCIe extended + configuration space.
The QEMU options starts with `x-` which usually means experimental and unsupported and we do not use unsupported options in libvirt.
``address`` The ``address`` element for USB devices has a ``bus`` and ``device`` attribute to specify the USB bus and device number the device appears at on @@ -9264,6 +9271,35 @@ Example: The ``pciBus`` attribute notes the index of the controller that an IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only)
+ ``accel`` + The ``accel`` attribute with possible values ``on`` and ``off`` can be used + to enable hardware acceleration support for smmuv3Dev IOMMU devices. + (QEMU/KVM and ``smmuv3`` model only) + + ``ats`` + The ``ats`` attribute with possible values ``on`` and ``off`` can be used + to enable reporting Address Translation Services capability to the guest + for smmuv3Dev IOMMU devices with ``accel`` set to ``on``, if the host + SMMUv3 supports ATS and the associated passthrough device supports ATS. + (QEMU/KVM and ``smmuv3`` model only)
This is the only one that QEMU doesn't validate if it's supported by host so cannot be currently enabled based on host and user needs to somehow figure out if this should be enabled or not.
+ ``ril`` + The ``ril`` attribute with possible values ``on`` and ``off`` can be used + to report whether Range Invalidation for smmuv3Dev IOMMU devices with + ``accel`` set to ``on`` is compatible with host SMMUv3 support. + (QEMU/KVM and ``smmuv3`` model only)
Current default in QEMU is `on` but if `accel` is enabled it has to match what is supported by host SMMUv3 and QEMU errors out if incorrect value is used. I wonder why QEMU cannot figure out the default value if nothing is specified? This way when acceleration is enabled and host SMMUv3 doesn't support RIL user needs to manually set this option as well.
+ + ``ssidSize`` + The ``ssidSize`` attribute sets the number of bits used to represent + SubstreamIDs. A value of N allows SSIDs in the range [0 .. 2^N - 1]. + The valid range is 0-20, and a value greater than 0 is required for + enabling PASID support, as doing so advertises PASID capability to + the vIOMMU. (QEMU/KVM and ``smmuv3`` model only)
By default this is disabled in QEMU and can be used only with accel enabled. If user picks 20 it can be still rejected by QEMU if the host doesn't support that size. Is this necessary to be enabled and what is reasonable default user should use?
+ ``oas`` + The ``oas`` attribute sets the output address size in units of bits. + (QEMU/KVM and ``smmuv3`` model only)
Currently supported values in QEMU are 44 and 48 bits. QEMU defaults to 44, if accel is off it has to be 44, if accel is on it can be 48. In addition QEMU also errors out if user sets OAS greater than what is supported by host. How is user supposed to figure this out and why QEMU cannot pick reasonable default?
The ``virtio`` IOMMU devices can further have ``address`` element as described in `Device addresses`_ (address has to by type of ``pci``).
For all these options we should store the default value in XML if user doesn't provide it to make sure that existing VMs will not change if QEMU changes its defaults. Pavel
Hi Pavel, On 2/23/2026 12:21 PM, Pavel Hrdina wrote:
+ ``ril`` + The ``ril`` attribute with possible values ``on`` and ``off`` can be used + to report whether Range Invalidation for smmuv3Dev IOMMU devices with + ``accel`` set to ``on`` is compatible with host SMMUv3 support. + (QEMU/KVM and ``smmuv3`` model only) Current default in QEMU is `on` but if `accel` is enabled it has to match what is supported by host SMMUv3 and QEMU errors out if incorrect value is used.
I wonder why QEMU cannot figure out the default value if nothing is specified? This way when acceleration is enabled and host SMMUv3 doesn't support RIL user needs to manually set this option as well.
+ + ``ssidSize`` + The ``ssidSize`` attribute sets the number of bits used to represent + SubstreamIDs. A value of N allows SSIDs in the range [0 .. 2^N - 1]. + The valid range is 0-20, and a value greater than 0 is required for + enabling PASID support, as doing so advertises PASID capability to + the vIOMMU. (QEMU/KVM and ``smmuv3`` model only) By default this is disabled in QEMU and can be used only with accel enabled. If user picks 20 it can be still rejected by QEMU if the host doesn't support that size.
Is this necessary to be enabled and what is reasonable default user should use?
+ ``oas`` + The ``oas`` attribute sets the output address size in units of bits. + (QEMU/KVM and ``smmuv3`` model only) Currently supported values in QEMU are 44 and 48 bits. QEMU defaults to 44, if accel is off it has to be 44, if accel is on it can be 48. In addition QEMU also errors out if user sets OAS greater than what is supported by host.
How is user supposed to figure this out and why QEMU cannot pick reasonable default?
The ``virtio`` IOMMU devices can further have ``address`` element as described in `Device addresses`_ (address has to by type of ``pci``). For all these options we should store the default value in XML if user doesn't provide it to make sure that existing VMs will not change if QEMU changes its defaults.
There has been some discussion on supporting an 'auto' value for these properties in the QEMU layer [0]. I think it would make sense to refresh this series with support for the 'auto' value, deriving these properties from host IOMMU capabilities so Libvirt users do not have to introspect host settings. Would you suggest consolidating this implementation into a single 'accel' driver attribute, and then setting the values for ril, ssidsize, and oas to 'auto' in the qemu command line when accel=on? Or still supporting user-defined values for ril, ssidsize, and oas but also supporting 'auto'? Noted for the latter option that we should store the default value in XML if user does not provide it. Thanks, Nathan [0] https://lore.kernel.org/qemu-devel/d9192ae6-a94f-479a-b19f-734cc52a6be0@redh...
On Tue, Feb 24, 2026 at 10:03:01AM -0800, Nathan Chen wrote:
Hi Pavel,
Hi Nathan,
On 2/23/2026 12:21 PM, Pavel Hrdina wrote:
+ ``ril`` + The ``ril`` attribute with possible values ``on`` and ``off`` can be used + to report whether Range Invalidation for smmuv3Dev IOMMU devices with + ``accel`` set to ``on`` is compatible with host SMMUv3 support. + (QEMU/KVM and ``smmuv3`` model only) Current default in QEMU is `on` but if `accel` is enabled it has to match what is supported by host SMMUv3 and QEMU errors out if incorrect value is used.
I wonder why QEMU cannot figure out the default value if nothing is specified? This way when acceleration is enabled and host SMMUv3 doesn't support RIL user needs to manually set this option as well.
+ + ``ssidSize`` + The ``ssidSize`` attribute sets the number of bits used to represent + SubstreamIDs. A value of N allows SSIDs in the range [0 .. 2^N - 1]. + The valid range is 0-20, and a value greater than 0 is required for + enabling PASID support, as doing so advertises PASID capability to + the vIOMMU. (QEMU/KVM and ``smmuv3`` model only) By default this is disabled in QEMU and can be used only with accel enabled. If user picks 20 it can be still rejected by QEMU if the host doesn't support that size.
Is this necessary to be enabled and what is reasonable default user should use?
+ ``oas`` + The ``oas`` attribute sets the output address size in units of bits. + (QEMU/KVM and ``smmuv3`` model only) Currently supported values in QEMU are 44 and 48 bits. QEMU defaults to 44, if accel is off it has to be 44, if accel is on it can be 48. In addition QEMU also errors out if user sets OAS greater than what is supported by host.
How is user supposed to figure this out and why QEMU cannot pick reasonable default?
The ``virtio`` IOMMU devices can further have ``address`` element as described in `Device addresses`_ (address has to by type of ``pci``). For all these options we should store the default value in XML if user doesn't provide it to make sure that existing VMs will not change if QEMU changes its defaults.
There has been some discussion on supporting an 'auto' value for these properties in the QEMU layer [0]. I think it would make sense to refresh this series with support for the 'auto' value, deriving these properties from host IOMMU capabilities so Libvirt users do not have to introspect host settings.
Would you suggest consolidating this implementation into a single 'accel' driver attribute, and then setting the values for ril, ssidsize, and oas to 'auto' in the qemu command line when accel=on? Or still supporting user-defined values for ril, ssidsize, and oas but also supporting 'auto'?
That depends if it's expected from users to change these values and why would they change them. For example ssidSize set to 0 disables PASID support, is it expected from users to disable this feature or set ssidsize to any specific value? If yes we need to have this attribute in XML but we should also use reasonable default that is supported by current host. RIL currently needs to be disabled but my guess is in the future it will be possible to have it enabled. OAS currently can be only 44 when accel is disabled, but can be 48 if accel is enabled, is it expected from users to use 44 with accel enabled? And in the future will there be any other value supported and possible used as default? Same for ATS, is it expected from users to disable it when accel is enabled? It also depends if migration of running VM with accelerated SMMUv3 is/will be supported. If yes we will need to have the current values in XML to make sure migration to different host with possibly different supported values will be rejected as otherwise the VM device would change. I would say it should be enough to set only `accel='on'` and the rest should be filled in using reasonable defaults unless it is explicitly specified in XML and every default should be stored in the XML. That should be ideally done when the VM is defined, so all values are stored in config XML, otherwise we would have to read the values from running QEMU process every time the VM is started. This would require QEMU to report the default values based on what host and QEMU supports via QAPI so libvirt can ask QEMU when defining new VM or libvirt would have to figure this out probing host directly. This means libvirt doesn't need adding `auto` as possible value for these properties. We could add `mode='host'` like it was done for virtio-iommu granule but IMO that should translate to `accel=host` on QEMU command line and QEMU should error out if any other property is set. Pavel
Thanks, Nathan
[0] https://lore.kernel.org/qemu-devel/d9192ae6-a94f-479a-b19f-734cc52a6be0@redh...
On 2/25/2026 5:07 AM, Pavel Hrdina wrote:
+ ``ril`` + The ``ril`` attribute with possible values ``on`` and ``off`` can be used + to report whether Range Invalidation for smmuv3Dev IOMMU devices with + ``accel`` set to ``on`` is compatible with host SMMUv3 support. + (QEMU/KVM and ``smmuv3`` model only) Current default in QEMU is `on` but if `accel` is enabled it has to match what is supported by host SMMUv3 and QEMU errors out if incorrect value is used.
I wonder why QEMU cannot figure out the default value if nothing is specified? This way when acceleration is enabled and host SMMUv3 doesn't support RIL user needs to manually set this option as well.
+ + ``ssidSize`` + The ``ssidSize`` attribute sets the number of bits used to represent + SubstreamIDs. A value of N allows SSIDs in the range [0 .. 2^N - 1]. + The valid range is 0-20, and a value greater than 0 is required for + enabling PASID support, as doing so advertises PASID capability to + the vIOMMU. (QEMU/KVM and ``smmuv3`` model only) By default this is disabled in QEMU and can be used only with accel enabled. If user picks 20 it can be still rejected by QEMU if the host doesn't support that size.
Is this necessary to be enabled and what is reasonable default user should use?
+ ``oas`` + The ``oas`` attribute sets the output address size in units of bits. + (QEMU/KVM and ``smmuv3`` model only) Currently supported values in QEMU are 44 and 48 bits. QEMU defaults to 44, if accel is off it has to be 44, if accel is on it can be 48. In addition QEMU also errors out if user sets OAS greater than what is supported by host.
How is user supposed to figure this out and why QEMU cannot pick reasonable default?
The ``virtio`` IOMMU devices can further have ``address`` element as described in `Device addresses`_ (address has to by type of ``pci``). For all these options we should store the default value in XML if user doesn't provide it to make sure that existing VMs will not change if QEMU changes its defaults. There has been some discussion on supporting an 'auto' value for these
On 2/23/2026 12:21 PM, Pavel Hrdina wrote: properties in the QEMU layer [0]. I think it would make sense to refresh this series with support for the 'auto' value, deriving these properties from host IOMMU capabilities so Libvirt users do not have to introspect host settings.
Would you suggest consolidating this implementation into a single 'accel' driver attribute, and then setting the values for ril, ssidsize, and oas to 'auto' in the qemu command line when accel=on? Or still supporting user-defined values for ril, ssidsize, and oas but also supporting 'auto'? That depends if it's expected from users to change these values and why would they change them.
For example ssidSize set to 0 disables PASID support, is it expected from users to disable this feature or set ssidsize to any specific value? If yes we need to have this attribute in XML but we should also use reasonable default that is supported by current host.
RIL currently needs to be disabled but my guess is in the future it will be possible to have it enabled.
OAS currently can be only 44 when accel is disabled, but can be 48 if accel is enabled, is it expected from users to use 44 with accel enabled? And in the future will there be any other value supported and possible used as default?
Same for ATS, is it expected from users to disable it when accel is enabled?
It also depends if migration of running VM with accelerated SMMUv3 is/will be supported. If yes we will need to have the current values in XML to make sure migration to different host with possibly different supported values will be rejected as otherwise the VM device would change.
I would say it should be enough to set only `accel='on'` and the rest should be filled in using reasonable defaults unless it is explicitly specified in XML and every default should be stored in the XML.
That should be ideally done when the VM is defined, so all values are stored in config XML, otherwise we would have to read the values from running QEMU process every time the VM is started.
This would require QEMU to report the default values based on what host and QEMU supports via QAPI so libvirt can ask QEMU when defining new VM or libvirt would have to figure this out probing host directly. This means libvirt doesn't need adding `auto` as possible value for these properties.
We could add `mode='host'` like it was done for virtio-iommu granule but IMO that should translate to `accel=host` on QEMU command line and QEMU should error out if any other property is set.
Thanks for the feedback, I think it makes sense to allow users to configure these options based on use cases if host doesn't support PASID, if users don't need SVA support and want to disable PASID for their work, if PASID width needs to be capped for compatibility, if there is no host support for RIL, if host or a device has broken ATS support, or if forcing oas=44 for compatibility. I will work on having QEMU report the default values for Libvirt to consume. Then the next Libvirt refresh will support having the default attribute values defined and stored if only `accel='on'` is specified. Nathan
On 2/25/2026 5:07 AM, Pavel Hrdina wrote:
+ ``ril`` + The ``ril`` attribute with possible values ``on`` and ``off`` can be used + to report whether Range Invalidation for smmuv3Dev IOMMU devices with + ``accel`` set to ``on`` is compatible with host SMMUv3 support. + (QEMU/KVM and ``smmuv3`` model only) Current default in QEMU is `on` but if `accel` is enabled it has to match what is supported by host SMMUv3 and QEMU errors out if incorrect value is used.
I wonder why QEMU cannot figure out the default value if nothing is specified? This way when acceleration is enabled and host SMMUv3 doesn't support RIL user needs to manually set this option as well.
+ + ``ssidSize`` + The ``ssidSize`` attribute sets the number of bits used to represent + SubstreamIDs. A value of N allows SSIDs in the range [0 .. 2^N - 1]. + The valid range is 0-20, and a value greater than 0 is required for + enabling PASID support, as doing so advertises PASID capability to + the vIOMMU. (QEMU/KVM and ``smmuv3`` model only) By default this is disabled in QEMU and can be used only with accel enabled. If user picks 20 it can be still rejected by QEMU if the host doesn't support that size.
Is this necessary to be enabled and what is reasonable default user should use?
+ ``oas`` + The ``oas`` attribute sets the output address size in units of bits. + (QEMU/KVM and ``smmuv3`` model only) Currently supported values in QEMU are 44 and 48 bits. QEMU defaults to 44, if accel is off it has to be 44, if accel is on it can be 48. In addition QEMU also errors out if user sets OAS greater than what is supported by host.
How is user supposed to figure this out and why QEMU cannot pick reasonable default?
The ``virtio`` IOMMU devices can further have ``address`` element as described in `Device addresses`_ (address has to by type of ``pci``). For all these options we should store the default value in XML if user doesn't provide it to make sure that existing VMs will not change if QEMU changes its defaults. There has been some discussion on supporting an 'auto' value for these
On 2/23/2026 12:21 PM, Pavel Hrdina wrote: properties in the QEMU layer [0]. I think it would make sense to refresh this series with support for the 'auto' value, deriving these properties from host IOMMU capabilities so Libvirt users do not have to introspect host settings.
Would you suggest consolidating this implementation into a single 'accel' driver attribute, and then setting the values for ril, ssidsize, and oas to 'auto' in the qemu command line when accel=on? Or still supporting user-defined values for ril, ssidsize, and oas but also supporting 'auto'? That depends if it's expected from users to change these values and why would they change them.
For example ssidSize set to 0 disables PASID support, is it expected from users to disable this feature or set ssidsize to any specific value? If yes we need to have this attribute in XML but we should also use reasonable default that is supported by current host.
RIL currently needs to be disabled but my guess is in the future it will be possible to have it enabled.
OAS currently can be only 44 when accel is disabled, but can be 48 if accel is enabled, is it expected from users to use 44 with accel enabled? And in the future will there be any other value supported and possible used as default?
Same for ATS, is it expected from users to disable it when accel is enabled?
It also depends if migration of running VM with accelerated SMMUv3 is/will be supported. If yes we will need to have the current values in XML to make sure migration to different host with possibly different supported values will be rejected as otherwise the VM device would change.
I would say it should be enough to set only `accel='on'` and the rest should be filled in using reasonable defaults unless it is explicitly specified in XML and every default should be stored in the XML.
That should be ideally done when the VM is defined, so all values are stored in config XML, otherwise we would have to read the values from running QEMU process every time the VM is started.
This would require QEMU to report the default values based on what host and QEMU supports via QAPI so libvirt can ask QEMU when defining new VM or libvirt would have to figure this out probing host directly. This means libvirt doesn't need adding `auto` as possible value for these properties.
We could add `mode='host'` like it was done for virtio-iommu granule but IMO that should translate to `accel=host` on QEMU command line and QEMU should error out if any other property is set.
I discussed the live migration use case with Shameer - it is currently not supported but QEMU should be checking if the resolved auto values match between source and target when live migration support is implemented, and prevent the migration if there is a mismatch. With that in mind, it seems like adding support for ril='auto',ats='auto', etc. without resolving the values in the XML should be OK to implement, but what are your thoughts? The issue with filling in reasonable defaults at libvirt XML definition time is that a device must be attached to iommufd context before these host SMMU properties can be queried. That means we would have to detect a device that's bound to a vSMMU in the XML, ensure it's not in use by other processes, and bind it to vfio-pci, and attach it to iommufd context at libvirt XML define time before a VM is actually booted. Another alternative which doesn't seem ideal either is to query the host SMMU properties after VM boots, then re-write the libvirt XML values set to 'auto' once the VM is booted. Thanks, Nathan
From: Nathan Chen <nathanc@nvidia.com> Provide sample XML and CLI args for the HW-accel smmuv3 XML schema for virt machine types. Signed-off-by: Nathan Chen <nathanc@nvidia.com> --- ...u-smmuv3-pci-bus-accel.aarch64-latest.args | 38 +++++++++++ ...mu-smmuv3-pci-bus-accel.aarch64-latest.xml | 64 +++++++++++++++++++ .../iommu-smmuv3-pci-bus-accel.xml | 54 ++++++++++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 157 insertions(+) create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.args create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.xml create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.xml diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.args b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.args new file mode 100644 index 0000000000..8af3fb41a9 --- /dev/null +++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.args @@ -0,0 +1,38 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/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":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-machine virt,usb=off,gic-version=2,dump-guest-core=off,memory-backend=mach-virt.ram,acpi=off \ +-accel tcg \ +-m size=1048576k \ +-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 \ +-device '{"driver":"pxb-pcie","bus_nr":252,"id":"pci.1","bus":"pcie.0","addr":"0x1"}' \ +-device '{"driver":"pxb-pcie","bus_nr":248,"id":"pci.2","bus":"pcie.0","addr":"0x2"}' \ +-device '{"driver":"pcie-root-port","port":0,"chassis":21,"id":"pci.3","bus":"pci.1","addr":"0x0"}' \ +-device '{"driver":"pcie-root-port","port":168,"chassis":22,"id":"pci.4","bus":"pci.2","addr":"0x0"}' \ +-device '{"driver":"arm-smmuv3","primary-bus":"pci.1","id":"iommu0","accel":true,"ats":true,"ril":false,"ssidsize":20,"oas":44}' \ +-device '{"driver":"arm-smmuv3","primary-bus":"pci.2","id":"iommu1","accel":true,"ats":true,"ril":false,"ssidsize":20,"oas":44}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device '{"driver":"vfio-pci","host":"0000:06:00.0","id":"hostdev0","x-vpasid-cap-offset":4088,"bus":"pci.3","addr":"0x0"}' \ +-device '{"driver":"vfio-pci","host":"0000:06:01.0","id":"hostdev1","bus":"pci.4","addr":"0x0"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.xml b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.xml new file mode 100644 index 0000000000..2132fb09b9 --- /dev/null +++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.aarch64-latest.xml @@ -0,0 +1,64 @@ +<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> + <boot dev='hd'/> + </os> + <features> + <gic version='2'/> + </features> + <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'/> + <controller type='pci' index='1' model='pcie-expander-bus'> + <model name='pxb-pcie'/> + <target busNr='252'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pcie-expander-bus'> + <model name='pxb-pcie'/> + <target busNr='248'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='21' port='0x0'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='22' port='0xa8'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> + </controller> + <audio id='1' type='none'/> + <hostdev mode='subsystem' type='pci' managed='no'> + <source> + <address domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> + </source> + <vpasidCapOffset>0xff8</vpasidCapOffset> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> + </hostdev> + <hostdev mode='subsystem' type='pci' managed='no'> + <source> + <address domain='0x0000' bus='0x06' slot='0x01' function='0x0'/> + </source> + <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> + </hostdev> + <memballoon model='none'/> + <iommu model='smmuv3'> + <driver pciBus='1' accel='on' ats='on' ril='off' ssidSize='20' oas='44'/> + </iommu> + <iommu model='smmuv3'> + <driver pciBus='2' accel='on' ats='on' ril='off' ssidSize='20' oas='44'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.xml b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.xml new file mode 100644 index 0000000000..adf5eb6740 --- /dev/null +++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel.xml @@ -0,0 +1,54 @@ +<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> + </os> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='pcie-expander-bus'> + <model name='pxb-pcie'/> + <target busNr='252'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pcie-expander-bus'> + <model name='pxb-pcie'/> + <target busNr='248'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='21' port='0x0'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='22' port='0xa8'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> + </controller> + <hostdev mode='subsystem' type='pci' managed='no'> + <source> + <address domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> + </source> + <vpasidCapOffset>0xff8</vpasidCapOffset> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> + </hostdev> + <hostdev mode='subsystem' type='pci' managed='no'> + <source> + <address domain='0x0000' bus='0x06' slot='0x01' function='0x0'/> + </source> + <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> + </hostdev> + <iommu model='smmuv3'> + <driver pciBus='1' accel='on' ats='on' ril='off' ssidSize='20' oas='44'/> + </iommu> + <iommu model='smmuv3'> + <driver pciBus='2' accel='on' ats='on' ril='off' ssidSize='20' oas='44'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 486d3d47ec..f82556c072 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -3060,6 +3060,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64"); DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3-pci-bus", "aarch64"); DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3-pci-bus-single", "aarch64"); + DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3-pci-bus-accel", "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"); -- 2.43.0
participants (2)
-
Nathan Chen -
Pavel Hrdina