From: Michal Privoznik <[email protected]> In PCI assignment scenario the virtio-iommu needs to know the guest page size also known as granule. Expose it as an attribute to the <driver/> element of a virtio-iommu.
This is possibly interesting only for aarch64 since it supports virtio-iommu and also supports running guests with different page size than the host. Signed-off-by: Michal Privoznik <[email protected]> --- docs/formatdomain.rst | 7 +++++ src/conf/domain_conf.c | 30 ++++++++++++++++++- src/conf/domain_conf.h | 13 ++++++++ src/conf/domain_validate.c | 9 ++++-- src/conf/schemas/domaincommon.rng | 11 +++++++ src/libvirt_private.syms | 2 ++ .../virtio-iommu-aarch64.aarch64-latest.xml | 2 +- .../qemuxmlconfdata/virtio-iommu-aarch64.xml | 2 +- 8 files changed, 70 insertions(+), 6 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 4b34a8a963..1dfe3915b5 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9264,6 +9264,13 @@ Example: The ``pciBus`` attribute notes the index of the controller that an IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only) + ``granule`` + This allows to choose which granule will be used by default by the + virtio-iommu and is useful when running guests with different page size + than the host. Accepted values are: ``4K``, ``8K``, ``16K``, ``64K`` and + ``host`` (matches the host page size). :since:`Since 12.1.0` (QEMU/KVM + and ``virtio`` 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 d00a43e969..140333b1ec 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1356,6 +1356,16 @@ VIR_ENUM_IMPL(virDomainIOMMUModel, "amd", ); +VIR_ENUM_IMPL(virDomainIOMMUGranuleMode, + VIR_DOMAIN_IOMMU_GRANULE_MODE_LAST, + "none", + "4K", + "8K", + "16K", + "64K", + "host", +); + VIR_ENUM_IMPL(virDomainVsockModel, VIR_DOMAIN_VSOCK_MODEL_LAST, "default", @@ -14514,6 +14524,12 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, if (virXMLPropInt(driver, "pciBus", 10, VIR_XML_PROP_NONE, &iommu->pci_bus, -1) < 0) return NULL; + + if (virXMLPropEnum(driver, "granule", + virDomainIOMMUGranuleModeTypeFromString, + VIR_XML_PROP_NONZERO, &iommu->granule_mode) < 0) { + return NULL; + } } if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, @@ -16565,7 +16581,8 @@ 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->granule_mode != b->granule_mode) return false; if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && @@ -22320,6 +22337,13 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, virTristateSwitchTypeToString(src->xtsup)); return false; } + if (src->granule_mode != dst->granule_mode) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device granule '%1$s' does not match source '%2$s'"), + virDomainIOMMUGranuleModeTypeToString(dst->granule_mode), + virDomainIOMMUGranuleModeTypeToString(src->granule_mode)); + return false; + } return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); } @@ -28645,6 +28669,10 @@ virDomainIOMMUDefFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " pciBus='%d'", iommu->pci_bus); } + if (iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { + virBufferAsprintf(&driverAttrBuf, " granule='%s'", + virDomainIOMMUGranuleModeTypeToString(iommu->granule_mode)); + } virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 83d49969d3..8ea620a738 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3050,6 +3050,17 @@ typedef enum { VIR_DOMAIN_IOMMU_MODEL_LAST } virDomainIOMMUModel; +typedef enum { + VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE = 0, + VIR_DOMAIN_IOMMU_GRANULE_MODE_4K, + VIR_DOMAIN_IOMMU_GRANULE_MODE_8K, + VIR_DOMAIN_IOMMU_GRANULE_MODE_16K, + VIR_DOMAIN_IOMMU_GRANULE_MODE_64K, + VIR_DOMAIN_IOMMU_GRANULE_MODE_HOST, + + VIR_DOMAIN_IOMMU_GRANULE_MODE_LAST +} virDomainIOMMUGranuleMode; + struct _virDomainIOMMUDef { virDomainIOMMUModel model; virTristateSwitch intremap; @@ -3062,6 +3073,7 @@ struct _virDomainIOMMUDef { virTristateSwitch dma_translation; virTristateSwitch xtsup; virTristateSwitch pt; + virDomainIOMMUGranuleMode granule_mode; }; typedef enum { @@ -4443,6 +4455,7 @@ VIR_ENUM_DECL(virDomainMemoryBackingModel); VIR_ENUM_DECL(virDomainMemorySource); VIR_ENUM_DECL(virDomainMemoryAllocation); VIR_ENUM_DECL(virDomainIOMMUModel); +VIR_ENUM_DECL(virDomainIOMMUGranuleMode); VIR_ENUM_DECL(virDomainVsockModel); VIR_ENUM_DECL(virDomainCryptoModel); VIR_ENUM_DECL(virDomainCryptoType); diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 440f23d726..fd28526159 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3194,7 +3194,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || - iommu->pt != VIR_TRISTATE_SWITCH_ABSENT) { + iommu->pt != VIR_TRISTATE_SWITCH_ABSENT || + iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); @@ -3226,7 +3227,8 @@ 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->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some additional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); @@ -3237,7 +3239,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->pci_bus >= 0) { + iommu->pci_bus >= 0 || + iommu->granule_mode != VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { 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..175e735a99 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6329,6 +6329,17 @@ <data type="unsignedInt"/> </attribute> </optional> + <optional> + <attribute name="granule"> + <choice> + <value>4K</value> + <value>8K</value> + <value>16K</value> + <value>64K</value> + <value>host</value> + </choice> + </attribute> + </optional> </element> </optional> <optional> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6bffd2eb6d..d34b65a415 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -499,6 +499,8 @@ virDomainIOMMUDefEquals; virDomainIOMMUDefFind; virDomainIOMMUDefFree; virDomainIOMMUDefNew; +virDomainIOMMUGranuleModeTypeFromString; +virDomainIOMMUGranuleModeTypeToString; virDomainIOMMUModelTypeFromString; virDomainIOMMUModelTypeToString; virDomainIOThreadIDAdd; diff --git a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml index 4ae628ab5a..709a24f796 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml +++ b/tests/qemuxmlconfdata/virtio-iommu-aarch64.aarch64-latest.xml @@ -29,7 +29,7 @@ <audio id='1' type='none'/> <memballoon model='none'/> <iommu model='virtio'> - <driver aw_bits='48'/> + <driver aw_bits='48' granule='64K'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> </iommu> </devices> diff --git a/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml b/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml index 96e5ea05ae..bf8bc58211 100644 --- a/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml +++ b/tests/qemuxmlconfdata/virtio-iommu-aarch64.xml @@ -14,7 +14,7 @@ <controller type='usb' model='none'/> <memballoon model='none'/> <iommu model='virtio'> - <driver aw_bits='48'/> + <driver aw_bits='48' granule='64K'/> </iommu> </devices> </domain> -- 2.52.0
