Correspond to 'x-scalable-mode' and 'x-flts' properties in QEMU.

Signed-off-by: Zhenzhong Duan <[email protected]>
---
 docs/formatdomain.rst             |  8 +++++++
 src/conf/domain_conf.c            | 35 ++++++++++++++++++++++++++++++-
 src/conf/domain_conf.h            |  2 ++
 src/conf/domain_validate.c        |  6 ++++++
 src/conf/schemas/domaincommon.rng | 10 +++++++++
 5 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index dcb24b1b23..cd130a3f51 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9250,6 +9250,14 @@ Example:
       The ``pciBus`` attribute notes the index of the controller that an
       IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only)
 
+   ``scalable_mode``
+      Enable scalable mode DMA translation.
+      :since:`Since 11.11.0` (QEMU/KVM and ``intel`` model only)
+
+   ``first_stage``
+      Enable first stage translation.
+      :since:`Since 11.11.0` (QEMU/KVM and ``intel`` 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 6e47ccb23d..5fd573c66b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14507,6 +14507,15 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt,
         if (virXMLPropInt(driver, "pciBus", 10, VIR_XML_PROP_NONE,
                           &iommu->pci_bus, -1) < 0)
             return NULL;
+
+        if (virXMLPropTristateSwitch(driver, "scalable_mode", 
VIR_XML_PROP_NONE,
+                                     &iommu->scalable_mode) < 0)
+            return NULL;
+
+        if (virXMLPropTristateSwitch(driver, "first_stage", VIR_XML_PROP_NONE,
+                                     &iommu->fsts) < 0)
+            return NULL;
+
     }
 
     if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt,
@@ -16558,7 +16567,9 @@ 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->scalable_mode != b->scalable_mode ||
+        a->fsts != b->fsts)
         return false;
 
     if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
@@ -22260,6 +22271,20 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef 
*src,
                        virTristateSwitchTypeToString(src->xtsup));
         return false;
     }
+    if (src->scalable_mode != dst->scalable_mode) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain IOMMU device dma translation '%1$s' 
does not match source '%2$s'"),
+                       virTristateSwitchTypeToString(dst->scalable_mode),
+                       virTristateSwitchTypeToString(src->scalable_mode));
+        return false;
+    }
+    if (src->fsts != dst->fsts) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain IOMMU device dma translation '%1$s' 
does not match source '%2$s'"),
+                       virTristateSwitchTypeToString(dst->fsts),
+                       virTristateSwitchTypeToString(src->fsts));
+        return false;
+    }
 
     return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
 }
@@ -28574,6 +28599,14 @@ virDomainIOMMUDefFormat(virBuffer *buf,
         virBufferAsprintf(&driverAttrBuf, " xtsup='%s'",
                           virTristateSwitchTypeToString(iommu->xtsup));
     }
+    if (iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT) {
+        virBufferAsprintf(&driverAttrBuf, " scalable_mode='%s'",
+                          virTristateSwitchTypeToString(iommu->scalable_mode));
+    }
+    if (iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT) {
+        virBufferAsprintf(&driverAttrBuf, " first_stage='%s'",
+                          virTristateSwitchTypeToString(iommu->fsts));
+    }
     if (iommu->pci_bus >= 0) {
         virBufferAsprintf(&driverAttrBuf, " pciBus='%d'",
                           iommu->pci_bus);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index da4ce9fc86..6e381e9b5a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3063,6 +3063,8 @@ struct _virDomainIOMMUDef {
     virTristateSwitch dma_translation;
     virTristateSwitch xtsup;
     virTristateSwitch pt;
+    virTristateSwitch scalable_mode;
+    virTristateSwitch fsts;
 };
 
 typedef enum {
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 8bbea5f000..27fe2b490e 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -3119,6 +3119,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
             iommu->aw_bits != 0 ||
             iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
             iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->fsts != 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"),
@@ -3133,6 +3135,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
             iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT ||
             iommu->aw_bits != 0 ||
             iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT ||
             iommu->pci_bus >= 0) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("iommu model '%1$s' doesn't support additional 
attributes"),
@@ -3146,6 +3150,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
             iommu->eim != VIR_TRISTATE_SWITCH_ABSENT ||
             iommu->aw_bits != 0 ||
             iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT ||
             iommu->pci_bus >= 0) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("iommu model '%1$s' doesn't support some 
additional attributes"),
diff --git a/src/conf/schemas/domaincommon.rng 
b/src/conf/schemas/domaincommon.rng
index 78cf0a08cf..394f23ff4d 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6332,6 +6332,16 @@
                 <data type="unsignedInt"/>
               </attribute>
             </optional>
+            <optional>
+              <attribute name="scalable_mode">
+                <ref name="virOnOff"/>
+              </attribute>
+            </optional>
+            <optional>
+              <attribute name="first_stage">
+                <ref name="virOnOff"/>
+              </attribute>
+            </optional>
           </element>
         </optional>
         <optional>
-- 
2.47.3

Reply via email to