[PATCH v3 2/3] qemu: Implement pluggable-device smmuv3

Nathan Chen via Devel posted 3 patches 2 weeks, 1 day ago
[PATCH v3 2/3] qemu: Implement pluggable-device smmuv3
Posted by Nathan Chen via Devel 2 weeks, 1 day ago
Introduce support for "pciBus" driver attribute for
"smmuv3" IOMMU model. The "pciBus" attribute indicates
the index of the controller that a smmuv3 IOMMU device
is attached to, and differentiates the device-pluggable
arm-smmuv3 model from the virt-machine-associated smmuv3
model.

Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
 docs/formatdomain.rst             |  4 ++
 src/conf/domain_conf.c            | 16 +++++++
 src/conf/domain_conf.h            |  1 +
 src/conf/domain_validate.c        | 28 ++++++++++--
 src/conf/schemas/domaincommon.rng |  5 ++
 src/qemu/qemu_command.c           | 76 ++++++++++++++++++++++++++++---
 6 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 4c245f41a9..a181462d13 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9238,6 +9238,10 @@ Example:
       Enable x2APIC mode. Useful for higher number of guest CPUs.
       :since:`Since 11.5.0` (QEMU/KVM and ``amd`` model only)
 
+   ``pciBus``
+      The ``pciBus`` attribute notes the index of the controller that an
+      IOMMU device is attached to. (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 a587dbf3e1..f3c1b3996e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2815,6 +2815,8 @@ virDomainIOMMUDefNew(void)
 
     iommu = g_new0(virDomainIOMMUDef, 1);
 
+    iommu->pci_bus = -1;
+
     return g_steal_pointer(&iommu);
 }
 
@@ -14497,6 +14499,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt,
         if (virXMLPropTristateSwitch(driver, "passthrough", VIR_XML_PROP_NONE,
                                      &iommu->pt) < 0)
             return NULL;
+
+        if (virXMLPropInt(driver, "pciBus", 10, VIR_XML_PROP_NONE,
+                          &iommu->pci_bus, -1) < 0)
+            return NULL;
     }
 
     if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt,
@@ -22194,6 +22200,12 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src,
                        dst->aw_bits, src->aw_bits);
         return false;
     }
+    if (src->pci_bus != dst->pci_bus) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain IOMMU device pci_bus value '%1$d' does not match source '%2$d'"),
+                       dst->pci_bus, src->pci_bus);
+        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'"),
@@ -28525,6 +28537,10 @@ virDomainIOMMUDefFormat(virBuffer *buf,
         virBufferAsprintf(&driverAttrBuf, " xtsup='%s'",
                           virTristateSwitchTypeToString(iommu->xtsup));
     }
+    if (iommu->pci_bus >= 0) {
+        virBufferAsprintf(&driverAttrBuf, " pciBus='%d'",
+                          iommu->pci_bus);
+    }
 
     virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f44e275270..4cf05d54e8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3055,6 +3055,7 @@ struct _virDomainIOMMUDef {
     virTristateSwitch eim;
     virTristateSwitch iotlb;
     unsigned int aw_bits;
+    int pci_bus;
     virDomainDeviceInfo info;
     virTristateSwitch dma_translation;
     virTristateSwitch xtsup;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 9fae071975..7f9d2c2fb6 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1865,6 +1865,11 @@ virDomainDefIOMMUValidate(const virDomainDef *def)
                            _("IOMMU model smmuv3 must be specified for multiple IOMMU definitions"));
         }
 
+        if (def->niommus > 1 && iommu->pci_bus < 0) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("device-pluggable IOMMU with pciBus attribute must be specified for multiple IOMMU definitions"));
+        }
+
         if (iommu->intremap == VIR_TRISTATE_SWITCH_ON &&
             def->features[VIR_DOMAIN_FEATURE_IOAPIC] != VIR_DOMAIN_IOAPIC_QEMU) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -3119,13 +3124,28 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
 {
     switch (iommu->model) {
     case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
+        if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT ||
+            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->xtsup != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->pt != VIR_TRISTATE_SWITCH_ABSENT) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("iommu model '%1$s' doesn't support some additional attributes"),
+                           virDomainIOMMUModelTypeToString(iommu->model));
+            return -1;
+        }
+        break;
     case VIR_DOMAIN_IOMMU_MODEL_VIRTIO:
         if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT ||
             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->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->pci_bus >= 0) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("iommu model '%1$s' doesn't support additional attributes"),
                            virDomainIOMMUModelTypeToString(iommu->model));
@@ -3137,7 +3157,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
         if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT ||
             iommu->eim != VIR_TRISTATE_SWITCH_ABSENT ||
             iommu->aw_bits != 0 ||
-            iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT) {
+            iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->pci_bus >= 0) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("iommu model '%1$s' doesn't support some additional attributes"),
                            virDomainIOMMUModelTypeToString(iommu->model));
@@ -3147,7 +3168,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->xtsup != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->pci_bus >= 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 ae3fa95904..9afc679258 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6322,6 +6322,11 @@
                 <ref name="virOnOff"/>
               </attribute>
             </optional>
+            <optional>
+              <attribute name="pciBus">
+                <data type="unsignedInt"/>
+              </attribute>
+            </optional>
           </element>
         </optional>
         <optional>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 97fe4267ec..ad749afc41 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6239,6 +6239,62 @@ qemuBuildBootCommandLine(virCommand *cmd,
 }
 
 
+static virJSONValue *
+qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
+                                 const virDomainIOMMUDef *iommu,
+                                 size_t id)
+{
+    g_autoptr(virJSONValue) props = NULL;
+    g_autofree char *bus = NULL;
+    g_autofree char *smmuv3_id = NULL;
+    size_t i;
+
+    for (i = 0; i < def->ncontrollers; i++) {
+        virDomainControllerDef *cont = def->controllers[i];
+        if (cont->idx == iommu->pci_bus) {
+            if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
+                const char *alias = cont->info.alias;
+
+                if (!alias)
+                    return NULL;
+
+                if (virDomainDeviceAliasIsUserAlias(alias)) {
+                    if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT &&
+                        iommu->pci_bus == 0) {
+                        if (qemuDomainSupportsPCIMultibus(def))
+                            bus = g_strdup("pci.0");
+                        else
+                            bus = g_strdup("pci");
+                    } else if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) {
+                        bus = g_strdup("pcie.0");
+                    }
+                } else {
+                    bus = g_strdup(alias);
+                }
+                break;
+            }
+        }
+    }
+
+    if (!bus) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("Could not find a suitable controller for smmuv3."));
+        return NULL;
+    }
+
+    smmuv3_id = g_strdup_printf("smmuv3.%zu", id);
+
+    if (virJSONValueObjectAdd(&props,
+                              "s:driver", "arm-smmuv3",
+                              "s:primary-bus", bus,
+                              "s:id", smmuv3_id,
+                              NULL) < 0)
+        return NULL;
+
+    return g_steal_pointer(&props);
+}
+
+
 static int
 qemuBuildIOMMUCommandLine(virCommand *cmd,
                           const virDomainDef *def,
@@ -6286,9 +6342,6 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
                 return -1;
 
             return 0;
-        case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
-            /* There is no -device for SMMUv3, so nothing to be done here */
-            return 0;
 
         case VIR_DOMAIN_IOMMU_MODEL_AMD:
             if (virJSONValueObjectAdd(&wrapperProps,
@@ -6318,6 +6371,17 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
 
             return 0;
 
+        case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
+            if (iommu->pci_bus >= 0) {
+                if (!(props = qemuBuildPCINestedSmmuv3DevProps(def, iommu, i)))
+                    return -1;
+                if (qemuBuildDeviceCommandlineFromJSON(cmd, props, def, qemuCaps) < 0)
+                    return -1;
+                break;
+            } else {
+                return 0;
+            }
+
         case VIR_DOMAIN_IOMMU_MODEL_LAST:
         default:
             virReportEnumRangeError(virDomainIOMMUModel, iommu->model);
@@ -10822,15 +10886,15 @@ qemuBuildCommandLine(virDomainObj *vm,
     if (qemuBuildBootCommandLine(cmd, def) < 0)
         return NULL;
 
-    if (qemuBuildIOMMUCommandLine(cmd, def, qemuCaps) < 0)
-        return NULL;
-
     if (qemuBuildGlobalControllerCommandLine(cmd, def) < 0)
         return NULL;
 
     if (qemuBuildControllersCommandLine(cmd, def, qemuCaps) < 0)
         return NULL;
 
+    if (qemuBuildIOMMUCommandLine(cmd, def, qemuCaps) < 0)
+        return NULL;
+
     if (qemuBuildMemoryDeviceCommandLine(cmd, cfg, def, priv) < 0)
         return NULL;
 
-- 
2.43.0
Re: [PATCH v3 2/3] qemu: Implement pluggable-device smmuv3
Posted by Ján Tomko via Devel 2 days, 15 hours ago
On a Wednesday in 2025, Nathan Chen via Devel wrote:
>Introduce support for "pciBus" driver attribute for
>"smmuv3" IOMMU model. The "pciBus" attribute indicates
>the index of the controller that a smmuv3 IOMMU device
>is attached to, and differentiates the device-pluggable
>arm-smmuv3 model from the virt-machine-associated smmuv3
>model.
>
>Signed-off-by: Nathan Chen <nathanc@nvidia.com>
>---
> docs/formatdomain.rst             |  4 ++
> src/conf/domain_conf.c            | 16 +++++++
> src/conf/domain_conf.h            |  1 +
> src/conf/domain_validate.c        | 28 ++++++++++--
> src/conf/schemas/domaincommon.rng |  5 ++
> src/qemu/qemu_command.c           | 76 ++++++++++++++++++++++++++++---
> 6 files changed, 121 insertions(+), 9 deletions(-)
>
>diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
>index 4c245f41a9..a181462d13 100644
>--- a/docs/formatdomain.rst
>+++ b/docs/formatdomain.rst
>@@ -9238,6 +9238,10 @@ Example:
>       Enable x2APIC mode. Useful for higher number of guest CPUs.
>       :since:`Since 11.5.0` (QEMU/KVM and ``amd`` model only)
>
>+   ``pciBus``
>+      The ``pciBus`` attribute notes the index of the controller that an
>+      IOMMU device is attached to. (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/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
>index ae3fa95904..9afc679258 100644
>--- a/src/conf/schemas/domaincommon.rng
>+++ b/src/conf/schemas/domaincommon.rng
>@@ -6322,6 +6322,11 @@
>                 <ref name="virOnOff"/>
>               </attribute>
>             </optional>
>+            <optional>
>+              <attribute name="pciBus">
>+                <data type="unsignedInt"/>
>+              </attribute>
>+            </optional>
>           </element>
>         </optional>
>         <optional>
>diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
>index 97fe4267ec..ad749afc41 100644
>--- a/src/qemu/qemu_command.c
>+++ b/src/qemu/qemu_command.c
>@@ -6239,6 +6239,62 @@ qemuBuildBootCommandLine(virCommand *cmd,
> }
>
>
>+static virJSONValue *
>+qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
>+                                 const virDomainIOMMUDef *iommu,
>+                                 size_t id)
>+{
>+    g_autoptr(virJSONValue) props = NULL;
>+    g_autofree char *bus = NULL;
>+    g_autofree char *smmuv3_id = NULL;
>+    size_t i;
>+

>+    for (i = 0; i < def->ncontrollers; i++) {
>+        virDomainControllerDef *cont = def->controllers[i];
>+        if (cont->idx == iommu->pci_bus) {
>+            if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
>+                const char *alias = cont->info.alias;
>+
>+                if (!alias)
>+                    return NULL;
>+
>+                if (virDomainDeviceAliasIsUserAlias(alias)) {
>+                    if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT &&
>+                        iommu->pci_bus == 0) {
>+                        if (qemuDomainSupportsPCIMultibus(def))
>+                            bus = g_strdup("pci.0");
>+                        else
>+                            bus = g_strdup("pci");
>+                    } else if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) {
>+                        bus = g_strdup("pcie.0");
>+                    }
>+                } else {
>+                    bus = g_strdup(alias);
>+                }
>+                break;
>+            }
>+        }
>+    }

This duplicates parts of 'qemuBuildDeviceAddressPCIGetBus'

>+
>+    if (!bus) {
>+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>+                        _("Could not find a suitable controller for smmuv3."));
>+        return NULL;
>+    }
>+
>+    smmuv3_id = g_strdup_printf("smmuv3.%zu", id);
>+
>+    if (virJSONValueObjectAdd(&props,
>+                              "s:driver", "arm-smmuv3",
>+                              "s:primary-bus", bus,
>+                              "s:id", smmuv3_id,
>+                              NULL) < 0)
>+        return NULL;
>+
>+    return g_steal_pointer(&props);
>+}
>+
>+
> static int
> qemuBuildIOMMUCommandLine(virCommand *cmd,
>                           const virDomainDef *def,
>@@ -6286,9 +6342,6 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
>                 return -1;
>
>             return 0;
>-        case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
>-            /* There is no -device for SMMUv3, so nothing to be done here */
>-            return 0;
>
>         case VIR_DOMAIN_IOMMU_MODEL_AMD:
>             if (virJSONValueObjectAdd(&wrapperProps,
>@@ -6318,6 +6371,17 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
>
>             return 0;
>
>+        case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
>+            if (iommu->pci_bus >= 0) {
>+                if (!(props = qemuBuildPCINestedSmmuv3DevProps(def, iommu, i)))
>+                    return -1;
>+                if (qemuBuildDeviceCommandlineFromJSON(cmd, props, def, qemuCaps) < 0)
>+                    return -1;
>+                break;
>+            } else {
>+                return 0;
>+            }

No need for the else branch.

>+
>         case VIR_DOMAIN_IOMMU_MODEL_LAST:
>         default:
>             virReportEnumRangeError(virDomainIOMMUModel, iommu->model);
>@@ -10822,15 +10886,15 @@ qemuBuildCommandLine(virDomainObj *vm,
>     if (qemuBuildBootCommandLine(cmd, def) < 0)
>         return NULL;
>
>-    if (qemuBuildIOMMUCommandLine(cmd, def, qemuCaps) < 0)
>-        return NULL;
>-
>     if (qemuBuildGlobalControllerCommandLine(cmd, def) < 0)
>         return NULL;
>
>     if (qemuBuildControllersCommandLine(cmd, def, qemuCaps) < 0)
>         return NULL;
>
>+    if (qemuBuildIOMMUCommandLine(cmd, def, qemuCaps) < 0)
>+        return NULL;
>+

Formatting the IOMMU devices after the controllers makes sense, but
should be in a separate patch.

>     if (qemuBuildMemoryDeviceCommandLine(cmd, cfg, def, priv) < 0)
>         return NULL;
>

Reviewed-by: Ján Tomko <jtomko@redhat.com>

Jano
Re: [PATCH v3 2/3] qemu: Implement pluggable-device smmuv3
Posted by Nathan Chen via Devel 1 day, 8 hours ago

On 11/18/2025 10:25 AM, Ján Tomko wrote:
> On a Wednesday in 2025, Nathan Chen via Devel wrote:
>> Introduce support for "pciBus" driver attribute for
>> "smmuv3" IOMMU model. The "pciBus" attribute indicates
>> the index of the controller that a smmuv3 IOMMU device
>> is attached to, and differentiates the device-pluggable
>> arm-smmuv3 model from the virt-machine-associated smmuv3
>> model.
>>
>> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
>> ---
>> docs/formatdomain.rst             |  4 ++
>> src/conf/domain_conf.c            | 16 +++++++
>> src/conf/domain_conf.h            |  1 +
>> src/conf/domain_validate.c        | 28 ++++++++++--
>> src/conf/schemas/domaincommon.rng |  5 ++
>> src/qemu/qemu_command.c           | 76 ++++++++++++++++++++++++++++---
>> 6 files changed, 121 insertions(+), 9 deletions(-)
>>
>> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
>> index 4c245f41a9..a181462d13 100644
>> --- a/docs/formatdomain.rst
>> +++ b/docs/formatdomain.rst
>> @@ -9238,6 +9238,10 @@ Example:
>>       Enable x2APIC mode. Useful for higher number of guest CPUs.
>>       :since:`Since 11.5.0` (QEMU/KVM and ``amd`` model only)
>>
>> +   ``pciBus``
>> +      The ``pciBus`` attribute notes the index of the controller that an
>> +      IOMMU device is attached to. (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/schemas/domaincommon.rng b/src/conf/schemas/ 
>> domaincommon.rng
>> index ae3fa95904..9afc679258 100644
>> --- a/src/conf/schemas/domaincommon.rng
>> +++ b/src/conf/schemas/domaincommon.rng
>> @@ -6322,6 +6322,11 @@
>>                 <ref name="virOnOff"/>
>>               </attribute>
>>             </optional>
>> +            <optional>
>> +              <attribute name="pciBus">
>> +                <data type="unsignedInt"/>
>> +              </attribute>
>> +            </optional>
>>           </element>
>>         </optional>
>>         <optional>
>> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
>> index 97fe4267ec..ad749afc41 100644
>> --- a/src/qemu/qemu_command.c
>> +++ b/src/qemu/qemu_command.c
>> @@ -6239,6 +6239,62 @@ qemuBuildBootCommandLine(virCommand *cmd,
>> }
>>
>>
>> +static virJSONValue *
>> +qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
>> +                                 const virDomainIOMMUDef *iommu,
>> +                                 size_t id)
>> +{
>> +    g_autoptr(virJSONValue) props = NULL;
>> +    g_autofree char *bus = NULL;
>> +    g_autofree char *smmuv3_id = NULL;
>> +    size_t i;
>> +
> 
>> +    for (i = 0; i < def->ncontrollers; i++) {
>> +        virDomainControllerDef *cont = def->controllers[i];
>> +        if (cont->idx == iommu->pci_bus) {
>> +            if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
>> +                const char *alias = cont->info.alias;
>> +
>> +                if (!alias)
>> +                    return NULL;
>> +
>> +                if (virDomainDeviceAliasIsUserAlias(alias)) {
>> +                    if (cont->model == 
>> VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT &&
>> +                        iommu->pci_bus == 0) {
>> +                        if (qemuDomainSupportsPCIMultibus(def))
>> +                            bus = g_strdup("pci.0");
>> +                        else
>> +                            bus = g_strdup("pci");
>> +                    } else if (cont->model == 
>> VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) {
>> +                        bus = g_strdup("pcie.0");
>> +                    }
>> +                } else {
>> +                    bus = g_strdup(alias);
>> +                }
>> +                break;
>> +            }
>> +        }
>> +    }
> 
> This duplicates parts of 'qemuBuildDeviceAddressPCIGetBus'
> 
>> +
>> +    if (!bus) {
>> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>> +                        _("Could not find a suitable controller for 
>> smmuv3."));
>> +        return NULL;
>> +    }
>> +
>> +    smmuv3_id = g_strdup_printf("smmuv3.%zu", id);
>> +
>> +    if (virJSONValueObjectAdd(&props,
>> +                              "s:driver", "arm-smmuv3",
>> +                              "s:primary-bus", bus,
>> +                              "s:id", smmuv3_id,
>> +                              NULL) < 0)
>> +        return NULL;
>> +
>> +    return g_steal_pointer(&props);
>> +}
>> +
>> +
>> static int
>> qemuBuildIOMMUCommandLine(virCommand *cmd,
>>                           const virDomainDef *def,
>> @@ -6286,9 +6342,6 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
>>                 return -1;
>>
>>             return 0;
>> -        case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
>> -            /* There is no -device for SMMUv3, so nothing to be done 
>> here */
>> -            return 0;
>>
>>         case VIR_DOMAIN_IOMMU_MODEL_AMD:
>>             if (virJSONValueObjectAdd(&wrapperProps,
>> @@ -6318,6 +6371,17 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
>>
>>             return 0;
>>
>> +        case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
>> +            if (iommu->pci_bus >= 0) {
>> +                if (!(props = qemuBuildPCINestedSmmuv3DevProps(def, 
>> iommu, i)))
>> +                    return -1;
>> +                if (qemuBuildDeviceCommandlineFromJSON(cmd, props, 
>> def, qemuCaps) < 0)
>> +                    return -1;
>> +                break;
>> +            } else {
>> +                return 0;
>> +            }
> 
> No need for the else branch.
> 
>> +
>>         case VIR_DOMAIN_IOMMU_MODEL_LAST:
>>         default:
>>             virReportEnumRangeError(virDomainIOMMUModel, iommu->model);
>> @@ -10822,15 +10886,15 @@ qemuBuildCommandLine(virDomainObj *vm,
>>     if (qemuBuildBootCommandLine(cmd, def) < 0)
>>         return NULL;
>>
>> -    if (qemuBuildIOMMUCommandLine(cmd, def, qemuCaps) < 0)
>> -        return NULL;
>> -
>>     if (qemuBuildGlobalControllerCommandLine(cmd, def) < 0)
>>         return NULL;
>>
>>     if (qemuBuildControllersCommandLine(cmd, def, qemuCaps) < 0)
>>         return NULL;
>>
>> +    if (qemuBuildIOMMUCommandLine(cmd, def, qemuCaps) < 0)
>> +        return NULL;
>> +
> 
> Formatting the IOMMU devices after the controllers makes sense, but
> should be in a separate patch.
> 
>>     if (qemuBuildMemoryDeviceCommandLine(cmd, cfg, def, priv) < 0)
>>         return NULL;
>>
> 
> Reviewed-by: Ján Tomko <jtomko@redhat.com>

Hi Jano,

Thank you for reviewing and providing feedback on these patches. I have 
sent out the next revision.

-Nathan