From nobody Mon Feb 2 07:30:41 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1769013137; cv=none; d=zohomail.com; s=zohoarc; b=m2fFyh64RHMD0yzhQjFfnPwy1fBbsOfdqtE4iq3QFKctXnvagn3vPr6iEFmjJq1kDZkVGxPdHYRV+Mx/uwIJUoPixyOXNsUDjcGyKuTKD1FaCA323OIPNoiuagg3Hp3mksrWTBU+HJp51T5sUWirlEtcVsqfgLRAUHvOEZ728wk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1769013137; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id:Cc; bh=MLEebI9ytyS+U6A7WpY1oYQ65Zn9UJAs4ygy2t8tLMA=; b=RdeWhdeOrZ0oyQIZQq15ZSZdqfp9A5EimjjaR2F8oIa4nVvgMIJOJFXl3VDVHHhtkxcj7KzlgGyPqk5OBuBDGAfHvvqPd6kWAaLXmhXRNR6pZURHr0mLzJRLhxBgTWac7+jspdUwjMxTDm3FW0j1ZdH21KVGm/74zE5loDKqnP8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1769013137428578.9433898550207; Wed, 21 Jan 2026 08:32:17 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 17B7B41E59; Wed, 21 Jan 2026 11:32:17 -0500 (EST) Received: from [172.19.199.3] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 7AF9D43F59; Wed, 21 Jan 2026 11:27:49 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 52BCC41C69; Wed, 21 Jan 2026 11:27:44 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 1ED8041A0D for ; Wed, 21 Jan 2026 11:27:32 -0500 (EST) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-380-0JT5bMJbOoWSt0GzMVCw8A-1; Wed, 21 Jan 2026 11:27:30 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 874C91800618 for ; Wed, 21 Jan 2026 16:27:29 +0000 (UTC) Received: from moe (unknown [10.43.3.236]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E3DB919560A7 for ; Wed, 21 Jan 2026 16:27:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1769012851; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MLEebI9ytyS+U6A7WpY1oYQ65Zn9UJAs4ygy2t8tLMA=; b=igCqxSHLoDn2I0H/B20hA82uE9XKzh5x3xYKCOoIuMoRusqZeokVJCaYVTndSElDlFLfVi 1By1scJjQTyfRoEqBjqjTDpplrakJsrPpgPmkmzHh09oHETIPpgInPeJo272EFiP2xP5k0 GSzj96NYe6HRehAbzo1v8LHyNaklqCw= X-MC-Unique: 0JT5bMJbOoWSt0GzMVCw8A-1 X-Mimecast-MFC-AGG-ID: 0JT5bMJbOoWSt0GzMVCw8A_1769012849 To: devel@lists.libvirt.org Subject: [PATCH 4/6] conf: Introduce granule attribute for virtio-iommu Date: Wed, 21 Jan 2026 17:27:20 +0100 Message-ID: <4f1d4ed20a65d16cb27add5c0abdfcbba86e6c48.1769012588.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: tcyhgrTXQ8IFrN42bIw0RgKnt-Wx9Ex5ulZv80qMmxQ_1769012849 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: EZYIY4KDTZGEPHJMHEKTIVOBBEHD26L6 X-Message-ID-Hash: EZYIY4KDTZGEPHJMHEKTIVOBBEHD26L6 X-MailFrom: mprivozn@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Michal Privoznik via Devel Reply-To: Michal Privoznik X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1769013139548158500 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Michal Privoznik 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 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 --- 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) =20 + ``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 s= ize + than the host. Accepted values are: ``4K``, ``8K``, ``16K``, ``64K``= and + ``host`` (matches the host page size). :since:`Since 12.1.0` (QEMU/K= VM + and ``virtio`` model only). + The ``virtio`` IOMMU devices can further have ``address`` element as descr= ibed in `Device addresses`_ (address has to by type of ``pci``). =20 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", ); =20 +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 *xmlo= pt, 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; + } } =20 if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, @@ -16565,7 +16581,8 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, a->eim !=3D b->eim || a->iotlb !=3D b->iotlb || a->aw_bits !=3D b->aw_bits || - a->dma_translation !=3D b->dma_translation) + a->dma_translation !=3D b->dma_translation || + a->granule_mode !=3D b->granule_mode) return false; =20 if (a->info.type !=3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && @@ -22320,6 +22337,13 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUD= ef *src, virTristateSwitchTypeToString(src->xtsup)); return false; } + if (src->granule_mode !=3D dst->granule_mode) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device granule '%1$s' does n= ot match source '%2$s'"), + virDomainIOMMUGranuleModeTypeToString(dst->granule_= mode), + virDomainIOMMUGranuleModeTypeToString(src->granule_= mode)); + return false; + } =20 return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); } @@ -28645,6 +28669,10 @@ virDomainIOMMUDefFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " pciBus=3D'%d'", iommu->pci_bus); } + if (iommu->granule_mode !=3D VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { + virBufferAsprintf(&driverAttrBuf, " granule=3D'%s'", + virDomainIOMMUGranuleModeTypeToString(iommu->gra= nule_mode)); + } =20 virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL); =20 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; =20 +typedef enum { + VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE =3D 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; }; =20 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 *io= mmu) iommu->aw_bits !=3D 0 || iommu->dma_translation !=3D VIR_TRISTATE_SWITCH_ABSENT || iommu->xtsup !=3D VIR_TRISTATE_SWITCH_ABSENT || - iommu->pt !=3D VIR_TRISTATE_SWITCH_ABSENT) { + iommu->pt !=3D VIR_TRISTATE_SWITCH_ABSENT || + iommu->granule_mode !=3D VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some addi= tional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); @@ -3226,7 +3227,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *io= mmu) iommu->eim !=3D VIR_TRISTATE_SWITCH_ABSENT || iommu->aw_bits !=3D 0 || iommu->dma_translation !=3D VIR_TRISTATE_SWITCH_ABSENT || - iommu->pci_bus >=3D 0) { + iommu->pci_bus >=3D 0 || + iommu->granule_mode !=3D VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some addi= tional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); @@ -3237,7 +3239,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *io= mmu) case VIR_DOMAIN_IOMMU_MODEL_INTEL: if (iommu->pt !=3D VIR_TRISTATE_SWITCH_ABSENT || iommu->xtsup !=3D VIR_TRISTATE_SWITCH_ABSENT || - iommu->pci_bus >=3D 0) { + iommu->pci_bus >=3D 0 || + iommu->granule_mode !=3D VIR_DOMAIN_IOMMU_GRANULE_MODE_NONE) { virReportError(VIR_ERR_XML_ERROR, _("iommu model '%1$s' doesn't support some addi= tional attributes"), virDomainIOMMUModelTypeToString(iommu->model)); diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincom= mon.rng index 114dd3f96f..175e735a99 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6329,6 +6329,17 @@ + + + + 4K + 8K + 16K + 64K + host + + + 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 @@