Correspond to 'x-scalable-mode' and 'x-flts' properties in QEMU. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- 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