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