From nobody Mon Jun 8 08:29:02 2026 Received: from out30-111.freemail.mail.aliyun.com (out30-111.freemail.mail.aliyun.com [115.124.30.111]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4EC92C11EE; Sun, 31 May 2026 09:36:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.111 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220219; cv=none; b=KOgSA7ThKW8WNgmuk7xIS9+jnsY/OzZqm+/lHJFhpzCuZM0odC/I/Arl0lN8LFkJsl0FAEyPnJrGSPRWX3Aum8YhhP6L0A4Ca0arzJIe30JueSq6IcnLvZG1/xK+l4x0ViHQu48bfsRt0mexkp2XNYShm5CSAWX7nuJ7/9W317M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220219; c=relaxed/simple; bh=MWe9/oEgZRQ7xd0rGrh+IR3Ep50p/ztOH/UAyNpyqq8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PphzIZdjyNURUQUCY7XoOt194e2fWvzF6PRdljgJkz3yBwO24u6q3l/097gI3pQJq1ZOA9RjdbzeSDpjJa/sPzhTanRsPY+tOOXrHKMt+DgAKXDEF94G89kKoadYMcGXnUuQLuVN1ZMPF5LoVxWO7wsox2rSf1PN7NtTbGu0J4s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=oqyvyY6M; arc=none smtp.client-ip=115.124.30.111 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="oqyvyY6M" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220209; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=BqI3wj50bY1yFeJVxmRBlmJ+T2V4ZAm9w/2StB4gVpI=; b=oqyvyY6M5uvxKe31topHX+dZz1vhgOhSYxSg+cmFTFJxOeoYg5GR0YoItqlFJG9xdGbq7K6QcuBAXdDYgn2dVrXu1Dsnf0tSwe3mROZmLv8B2I5aiAVJX8V2vX7DnPiEezCl/5u8FNG9XdhEopkTPFtUbFivyiwd1uQ3CCJZ6k8= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R471e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam011083073210;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVoG_1780220206; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVoG_1780220206 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:47 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 1/9] iommu: introduce iova_to_phys_length in iommu_domain_ops Date: Sun, 31 May 2026 17:36:29 +0800 Message-ID: <20260531093637.3893199-2-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add iova_to_phys_length callback to struct iommu_domain_ops alongside the existing iova_to_phys. The new callback returns both the physical address and the PTE mapping page size in a single page table walk. Add iommu_iova_to_phys_length() core function that: - Checks ops->iova_to_phys_length first (preferred path) - Falls back to ops->iova_to_phys for unmigrated drivers This enables callers like VFIO to efficiently traverse IOVA space by actual mapping granularity instead of fixed PAGE_SIZE steps. Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/iommu/iommu.c | 34 ++++++++++++++++++++++++++++++++-- include/linux/iommu.h | 9 +++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d1a9e713d3a0..43323229a1df 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2545,15 +2545,45 @@ void iommu_detach_group(struct iommu_domain *domain= , struct iommu_group *group) } EXPORT_SYMBOL_GPL(iommu_detach_group); =20 -phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iov= a) +/** + * iommu_iova_to_phys_length - Translate IOVA and return mapping page size + * @domain: IOMMU domain to query + * @iova: IO virtual address to translate + * @mapped_length: Output parameter for the PTE page size (e.g. 4KB/2MB/1G= B) + * + * Like iommu_iova_to_phys() but additionally returns the page size of the + * PTE mapping at @iova through @mapped_length. + * + * Return: The physical address for the given IOVA, or 0 if no translation. + */ +phys_addr_t iommu_iova_to_phys_length(struct iommu_domain *domain, + dma_addr_t iova, + size_t *mapped_length) { + if (mapped_length) + *mapped_length =3D 0; + if (domain->type =3D=3D IOMMU_DOMAIN_IDENTITY) return iova; =20 if (domain->type =3D=3D IOMMU_DOMAIN_BLOCKED) return 0; =20 - return domain->ops->iova_to_phys(domain, iova); + if (domain->ops->iova_to_phys_length) + return domain->ops->iova_to_phys_length(domain, iova, + mapped_length); + + /* Fallback to legacy iova_to_phys without length info */ + if (domain->ops->iova_to_phys) + return domain->ops->iova_to_phys(domain, iova); + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_iova_to_phys_length); + +phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iov= a) +{ + return iommu_iova_to_phys_length(domain, iova, NULL); } EXPORT_SYMBOL_GPL(iommu_iova_to_phys); =20 diff --git a/include/linux/iommu.h b/include/linux/iommu.h index e587d4ac4d33..19da84c2922c 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -747,6 +747,9 @@ struct iommu_ops { * invalidation requests. The driver data structure * must be defined in include/uapi/linux/iommufd.h * @iova_to_phys: translate iova to physical address + * @iova_to_phys_length: translate iova to physical address and additional= ly + * return the page size of the PTE mapping at @iova + * through @mapped_length. * @enforce_cache_coherency: Prevent any kind of DMA from bypassing IOMMU_= CACHE, * including no-snoop TLPs on PCIe or other plat= form * specific mechanisms. @@ -776,6 +779,9 @@ struct iommu_domain_ops { =20 phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova); + phys_addr_t (*iova_to_phys_length)(struct iommu_domain *domain, + dma_addr_t iova, + size_t *mapped_length); =20 bool (*enforce_cache_coherency)(struct iommu_domain *domain); int (*set_pgtable_quirks)(struct iommu_domain *domain, @@ -930,6 +936,9 @@ extern ssize_t iommu_map_sg(struct iommu_domain *domain= , unsigned long iova, struct scatterlist *sg, unsigned int nents, int prot, gfp_t gfp); extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_add= r_t iova); +extern phys_addr_t iommu_iova_to_phys_length(struct iommu_domain *domain, + dma_addr_t iova, + size_t *mapped_length); extern void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token); =20 --=20 2.43.7 From nobody Mon Jun 8 08:29:02 2026 Received: from out30-119.freemail.mail.aliyun.com (out30-119.freemail.mail.aliyun.com [115.124.30.119]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E17E26B764; Sun, 31 May 2026 09:36:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.119 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220216; cv=none; b=l7g+eDaJNuXB6VfAUk+ybhT/tlG2G70wY6DD6AnT4yqKkkUml1YG4YVXYW9a9HFeUV8iWeHHUohLsqPLE43iHbBXyMwEkA8HNDOwFPrzagTA/TzxkYufhogoBhOLzSvq/FDMvLzrABakxvlg+FsJVikEijPuuFgkodY1kpcb0Zg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220216; c=relaxed/simple; bh=56CnbH7DPyai/C45yASqaf7qDdf76MK8jaWWoLTdchs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ffedR0cQLc65KcYf9peVGMo7YAuCYnY5TON82Y0+CphIsF97wqLPUB2lSxg9OqEM+ImmF8lw5OWVh5WSGfRu2w7DaBcwguH8TkP+hHCATr5ACtp8Y0CTrD3akTqAnmTrgLrynHKhqAabrexdaZuQ5bYnTi0MabV8eXXLKSn8/sk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=tFhxoDmW; arc=none smtp.client-ip=115.124.30.119 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="tFhxoDmW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220210; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=WCcyCK7AkmgAFVYPsCQjJr2AQljQ2E/AGKpawKYklUI=; b=tFhxoDmWv3ikGXax2dU+vD9Ab0ubDadUHCgely6f32fFtFge5I4HoSC6HAkCq8Q2fbAdveIyFkZDrHfNH2noSMckb/n7glyyc+SQ2mUcIXWUr00qnoPjlhCRc1UBHNzXIh4cNZXIhreYDIQj/X0kCFsrI0SmT+h4svSEadlWXHI= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R191e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033045098064;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVog_1780220207; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVog_1780220207 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:48 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 2/9] iommu/io-pgtable: introduce iova_to_phys_length in io_pgtable_ops Date: Sun, 31 May 2026 17:36:30 +0800 Message-ID: <20260531093637.3893199-3-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add iova_to_phys_length to struct io_pgtable_ops alongside iova_to_phys. The new callback additionally returns the block/page size of the PTE entry through the mapped_length parameter. Implement in all three io-pgtable backends: - ARM LPAE: returns ARM_LPAE_BLOCK_SIZE at the resolved level - ARM v7s: returns block size derived from level mask - DART: returns pgsize_bitmap (single fixed page size) The old iova_to_phys is kept as a thin wrapper for backward compat. Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/iommu/io-pgtable-arm-v7s.c | 30 ++++++++++++++++++++++++------ drivers/iommu/io-pgtable-arm.c | 19 ++++++++++++++++++- drivers/iommu/io-pgtable-dart.c | 26 +++++++++++++++++++++----- include/linux/io-pgtable.h | 7 +++++++ 4 files changed, 70 insertions(+), 12 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-= arm-v7s.c index 40e33257d3c2..54e8cc673eb6 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c @@ -641,13 +641,25 @@ static size_t arm_v7s_unmap_pages(struct io_pgtable_o= ps *ops, unsigned long iova return unmapped; } =20 +static phys_addr_t arm_v7s_iova_to_phys_length(struct io_pgtable_ops *ops, + unsigned long iova, + size_t *mapped_length); + static phys_addr_t arm_v7s_iova_to_phys(struct io_pgtable_ops *ops, unsigned long iova) +{ + return arm_v7s_iova_to_phys_length(ops, iova, NULL); +} + +static phys_addr_t arm_v7s_iova_to_phys_length(struct io_pgtable_ops *ops, + unsigned long iova, + size_t *mapped_length) { struct arm_v7s_io_pgtable *data =3D io_pgtable_ops_to_data(ops); arm_v7s_iopte *ptep =3D data->pgd, pte; int lvl =3D 0; u32 mask; + size_t blk_size; =20 do { ptep +=3D ARM_V7S_LVL_IDX(iova, ++lvl, &data->iop.cfg); @@ -661,6 +673,11 @@ static phys_addr_t arm_v7s_iova_to_phys(struct io_pgta= ble_ops *ops, mask =3D ARM_V7S_LVL_MASK(lvl); if (arm_v7s_pte_is_cont(pte, lvl)) mask *=3D ARM_V7S_CONT_PAGES; + + blk_size =3D ~mask + 1U; + if (mapped_length) + *mapped_length =3D blk_size; + return iopte_to_paddr(pte, lvl, &data->iop.cfg) | (iova & ~mask); } =20 @@ -714,6 +731,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct = io_pgtable_cfg *cfg, .map_pages =3D arm_v7s_map_pages, .unmap_pages =3D arm_v7s_unmap_pages, .iova_to_phys =3D arm_v7s_iova_to_phys, + .iova_to_phys_length =3D arm_v7s_iova_to_phys_length, }; =20 /* We have to do this early for __arm_v7s_alloc_table to work... */ @@ -837,13 +855,13 @@ static int __init arm_v7s_do_selftests(void) * Initial sanity checks. * Empty page tables shouldn't provide any translations. */ - if (ops->iova_to_phys(ops, 42)) + if (ops->iova_to_phys_length(ops, 42, NULL)) return __FAIL(ops); =20 - if (ops->iova_to_phys(ops, SZ_1G + 42)) + if (ops->iova_to_phys_length(ops, SZ_1G + 42, NULL)) return __FAIL(ops); =20 - if (ops->iova_to_phys(ops, SZ_2G + 42)) + if (ops->iova_to_phys_length(ops, SZ_2G + 42, NULL)) return __FAIL(ops); =20 /* @@ -864,7 +882,7 @@ static int __init arm_v7s_do_selftests(void) &mapped)) return __FAIL(ops); =20 - if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) + if (ops->iova_to_phys_length(ops, iova + 42, NULL) !=3D (iova + 42)) return __FAIL(ops); =20 iova +=3D SZ_16M; @@ -878,7 +896,7 @@ static int __init arm_v7s_do_selftests(void) if (ops->unmap_pages(ops, iova, size, 1, NULL) !=3D size) return __FAIL(ops); =20 - if (ops->iova_to_phys(ops, iova + 42)) + if (ops->iova_to_phys_length(ops, iova + 42, NULL)) return __FAIL(ops); =20 /* Remap full block */ @@ -886,7 +904,7 @@ static int __init arm_v7s_do_selftests(void) GFP_KERNEL, &mapped)) return __FAIL(ops); =20 - if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) + if (ops->iova_to_phys_length(ops, iova + 42, NULL) !=3D (iova + 42)) return __FAIL(ops); =20 iova +=3D SZ_16M; diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 0208e5897c29..e2ea84669fbf 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -731,8 +731,19 @@ static int visit_iova_to_phys(struct io_pgtable_walk_d= ata *walk_data, int lvl, return 0; } =20 +static phys_addr_t arm_lpae_iova_to_phys_length(struct io_pgtable_ops *ops, + unsigned long iova, + size_t *mapped_length); + static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops, unsigned long iova) +{ + return arm_lpae_iova_to_phys_length(ops, iova, NULL); +} + +static phys_addr_t arm_lpae_iova_to_phys_length(struct io_pgtable_ops *ops, + unsigned long iova, + size_t *mapped_length) { struct arm_lpae_io_pgtable *data =3D io_pgtable_ops_to_data(ops); struct iova_to_phys_data d; @@ -742,13 +753,18 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pg= table_ops *ops, .addr =3D iova, .end =3D iova + 1, }; + size_t block_size; int ret; =20 ret =3D __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_le= vel); if (ret) return 0; =20 - iova &=3D (ARM_LPAE_BLOCK_SIZE(d.lvl, data) - 1); + block_size =3D ARM_LPAE_BLOCK_SIZE(d.lvl, data); + if (mapped_length) + *mapped_length =3D block_size; + + iova &=3D (block_size - 1); return iopte_to_paddr(d.pte, data) | iova; } =20 @@ -948,6 +964,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg) .map_pages =3D arm_lpae_map_pages, .unmap_pages =3D arm_lpae_unmap_pages, .iova_to_phys =3D arm_lpae_iova_to_phys, + .iova_to_phys_length =3D arm_lpae_iova_to_phys_length, .read_and_clear_dirty =3D arm_lpae_read_and_clear_dirty, .pgtable_walk =3D arm_lpae_pgtable_walk, }; diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dar= t.c index cbc5d6aa2daa..fa250f5d16ed 100644 --- a/drivers/iommu/io-pgtable-dart.c +++ b/drivers/iommu/io-pgtable-dart.c @@ -333,11 +333,23 @@ static size_t dart_unmap_pages(struct io_pgtable_ops = *ops, unsigned long iova, return i * pgsize; } =20 +static phys_addr_t dart_iova_to_phys_length(struct io_pgtable_ops *ops, + unsigned long iova, + size_t *mapped_length); + static phys_addr_t dart_iova_to_phys(struct io_pgtable_ops *ops, - unsigned long iova) + unsigned long iova) +{ + return dart_iova_to_phys_length(ops, iova, NULL); +} + +static phys_addr_t dart_iova_to_phys_length(struct io_pgtable_ops *ops, + unsigned long iova, + size_t *mapped_length) { struct dart_io_pgtable *data =3D io_pgtable_ops_to_data(ops); dart_iopte pte, *ptep; + size_t pgsize; =20 ptep =3D dart_get_last(data, iova); =20 @@ -350,7 +362,10 @@ static phys_addr_t dart_iova_to_phys(struct io_pgtable= _ops *ops, pte =3D READ_ONCE(*ptep); /* Found translation */ if (pte) { - iova &=3D (data->iop.cfg.pgsize_bitmap - 1); + pgsize =3D data->iop.cfg.pgsize_bitmap; + if (mapped_length) + *mapped_length =3D pgsize; + iova &=3D (pgsize - 1); return iopte_to_paddr(pte, data) | iova; } =20 @@ -397,9 +412,10 @@ dart_alloc_pgtable(struct io_pgtable_cfg *cfg) data->bits_per_level =3D bits_per_level; =20 data->iop.ops =3D (struct io_pgtable_ops) { - .map_pages =3D dart_map_pages, - .unmap_pages =3D dart_unmap_pages, - .iova_to_phys =3D dart_iova_to_phys, + .map_pages =3D dart_map_pages, + .unmap_pages =3D dart_unmap_pages, + .iova_to_phys =3D dart_iova_to_phys, + .iova_to_phys_length =3D dart_iova_to_phys_length, }; =20 return data; diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index e19872e37e06..42bcdd309b88 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -203,6 +203,10 @@ struct arm_lpae_io_pgtable_walk_data { * @map_pages: Map a physically contiguous range of pages of the same s= ize. * @unmap_pages: Unmap a range of virtually contiguous pages of the same = size. * @iova_to_phys: Translate iova to physical address. + * @iova_to_phys_length: Translate iova to physical address and return the + * remaining mapped length from iova to the end of the + * mapping entry via @mapped_length. If @mapped_length is + * NULL, only the physical address is returned. * @pgtable_walk: (optional) Perform a page table walk for a given iova. * @read_and_clear_dirty: Record dirty info per IOVA. If an IOVA is dirty, * clear its dirty state from the PTE unless the @@ -220,6 +224,9 @@ struct io_pgtable_ops { struct iommu_iotlb_gather *gather); phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops, unsigned long iova); + phys_addr_t (*iova_to_phys_length)(struct io_pgtable_ops *ops, + unsigned long iova, + size_t *mapped_length); int (*pgtable_walk)(struct io_pgtable_ops *ops, unsigned long iova, void = *wd); int (*read_and_clear_dirty)(struct io_pgtable_ops *ops, unsigned long iova, size_t size, --=20 2.43.7 From nobody Mon Jun 8 08:29:02 2026 Received: from out30-113.freemail.mail.aliyun.com (out30-113.freemail.mail.aliyun.com [115.124.30.113]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38462284693; Sun, 31 May 2026 09:36:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.113 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220223; cv=none; b=UgwET1s3BlgM9HczS2FPV+smusHhLSHaG7yyb6GcqR2P0whql849+7ZsJJ3Nj3vYjn0cx8raOG5EUXuRnbJPABKXGjqXhB5iIm864zJ+exlcwNvwJ0K48HrWr3XaXDZsXAgc3wsSOI+Cq3L5gK4Dqj7+lcgbBj2dZgx16WNxtpE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220223; c=relaxed/simple; bh=iLQcwMf/oi8dHVQcgWWjIA6zHLhoK4I+57Up6+nLYJQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GUUsUbyscmvlQakhWNgFwQXabW8Vi+4HkUuq+7uoIiKI+XbD85hIp4xcB5DQGlO7m+D1m+IkhSG8tuQiMBETofu29TqAGfOUu9dX7MGPnZquxvb9+Ckh3hdmOInniKLuzsLDr9H5VW3oweRnr56rBVGyi7tS7YTQMxjVvKpTvmU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=nOa4AsRY; arc=none smtp.client-ip=115.124.30.113 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="nOa4AsRY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220211; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=ar0N90nh7aOdbVxftACZsIGW+S3DboQEhi1itlPEca8=; b=nOa4AsRYPIlSQmTF7ipwiiT7K/euo6c6Io9nBzdf5OQqr8Fpef4pn1EMYT7VZr7+Ag0zWq//YR+/S48I5Eu284BaaOG9cJHIuaSv8IspJJ8Ra1EdRxCvWLtt8b2+zb85fxkifFiBTeYSNMG2G/A+jIophHActe09QOUw9LX8S0Y= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R851e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033037009110;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVpJ_1780220209; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVpJ_1780220209 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:49 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 3/9] iommu/generic_pt: implement iova_to_phys_length Date: Sun, 31 May 2026 17:36:31 +0800 Message-ID: <20260531093637.3893199-4-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend the Generic Page Table framework to implement iova_to_phys_length. Use pt_entry_oa_lg2sz() to determine PTE block size. Update IOMMU_PT_DOMAIN_OPS macro to set .iova_to_phys_length. Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/iommu/generic_pt/iommu_pt.h | 49 ++++++++++++++++++----------- include/linux/generic_pt/iommu.h | 13 ++++---- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/drivers/iommu/generic_pt/iommu_pt.h b/drivers/iommu/generic_pt= /iommu_pt.h index dc91fb4e2f61..b4213b4947f2 100644 --- a/drivers/iommu/generic_pt/iommu_pt.h +++ b/drivers/iommu/generic_pt/iommu_pt.h @@ -145,13 +145,18 @@ static inline unsigned int compute_best_pgsize(struct= pt_state *pts, pts->range->va, pts->range->last_va, oa); } =20 -static __always_inline int __do_iova_to_phys(struct pt_range *range, void = *arg, - unsigned int level, - struct pt_table_p *table, - pt_level_fn_t descend_fn) +struct iova_to_phys_length_data { + pt_oaddr_t phys; + size_t length; +}; + +static __always_inline int __do_iova_to_phys_length(struct pt_range *range, + void *arg, unsigned int level, + struct pt_table_p *table, + pt_level_fn_t descend_fn) { struct pt_state pts =3D pt_init(range, level, table); - pt_oaddr_t *res =3D arg; + struct iova_to_phys_length_data *data =3D arg; =20 switch (pt_load_single_entry(&pts)) { case PT_ENTRY_EMPTY: @@ -159,45 +164,51 @@ static __always_inline int __do_iova_to_phys(struct p= t_range *range, void *arg, case PT_ENTRY_TABLE: return pt_descend(&pts, arg, descend_fn); case PT_ENTRY_OA: - *res =3D pt_entry_oa_exact(&pts); + data->phys =3D pt_entry_oa_exact(&pts); + data->length =3D BIT(pt_entry_oa_lg2sz(&pts)); return 0; } return -ENOENT; } -PT_MAKE_LEVELS(__iova_to_phys, __do_iova_to_phys); +PT_MAKE_LEVELS(__iova_to_phys_length, __do_iova_to_phys_length); =20 /** - * iova_to_phys() - Return the output address for the given IOVA + * iova_to_phys_length() - Translate IOVA returning both phys and page size * @domain: Table to query * @iova: IO virtual address to query + * @mapped_length: Output for the PTE page size in bytes * - * Determine the output address from the given IOVA. @iova may have any - * alignment, the returned physical will be adjusted with any sub page off= set. + * Walk the IOMMU page table to translate @iova to a physical address while + * also returning the page size of the PTE entry through @mapped_length. + * This combines iova_to_phys and page size query into a single page table= walk. * * Context: The caller must hold a read range lock that includes @iova. * - * Return: 0 if there is no translation for the given iova. + * Return: The physical address, or 0 if there is no translation. */ -phys_addr_t DOMAIN_NS(iova_to_phys)(struct iommu_domain *domain, - dma_addr_t iova) +phys_addr_t DOMAIN_NS(iova_to_phys_length)(struct iommu_domain *domain, + dma_addr_t iova, + size_t *mapped_length) { struct pt_iommu *iommu_table =3D container_of(domain, struct pt_iommu, domain); struct pt_range range; - pt_oaddr_t res; + struct iova_to_phys_length_data data; int ret; =20 ret =3D make_range(common_from_iommu(iommu_table), &range, iova, 1); if (ret) - return ret; + return 0; =20 - ret =3D pt_walk_range(&range, __iova_to_phys, &res); - /* PHYS_ADDR_MAX would be a better error code */ + ret =3D pt_walk_range(&range, __iova_to_phys_length, &data); if (ret) return 0; - return res; + + if (mapped_length) + *mapped_length =3D data.length; + return data.phys; } -EXPORT_SYMBOL_NS_GPL(DOMAIN_NS(iova_to_phys), "GENERIC_PT_IOMMU"); +EXPORT_SYMBOL_NS_GPL(DOMAIN_NS(iova_to_phys_length), "GENERIC_PT_IOMMU"); =20 struct pt_iommu_dirty_args { struct iommu_dirty_bitmap *dirty; diff --git a/include/linux/generic_pt/iommu.h b/include/linux/generic_pt/io= mmu.h index dd0edd02a48a..859b853e9dc7 100644 --- a/include/linux/generic_pt/iommu.h +++ b/include/linux/generic_pt/iommu.h @@ -249,8 +249,9 @@ struct pt_iommu_cfg { =20 /* Generate the exported function signatures from iommu_pt.h */ #define IOMMU_PROTOTYPES(fmt) = \ - phys_addr_t pt_iommu_##fmt##_iova_to_phys(struct iommu_domain *domain, \ - dma_addr_t iova); \ + phys_addr_t pt_iommu_##fmt##_iova_to_phys_length( \ + struct iommu_domain *domain, dma_addr_t iova, \ + size_t *mapped_length); \ int pt_iommu_##fmt##_read_and_clear_dirty( \ struct iommu_domain *domain, unsigned long iova, size_t size, \ unsigned long flags, struct iommu_dirty_bitmap *dirty); \ @@ -267,11 +268,11 @@ struct pt_iommu_cfg { IOMMU_PROTOTYPES(fmt) =20 /* - * A driver uses IOMMU_PT_DOMAIN_OPS to populate the iommu_domain_ops for = the - * iommu_pt + * A driver uses IOMMU_PT_DOMAIN_OPS to populate the iommu_domain_ops for + * the iommu_pt */ -#define IOMMU_PT_DOMAIN_OPS(fmt) \ - .iova_to_phys =3D &pt_iommu_##fmt##_iova_to_phys +#define IOMMU_PT_DOMAIN_OPS(fmt) \ + .iova_to_phys_length =3D &pt_iommu_##fmt##_iova_to_phys_length #define IOMMU_PT_DIRTY_OPS(fmt) \ .read_and_clear_dirty =3D &pt_iommu_##fmt##_read_and_clear_dirty =20 --=20 2.43.7 From nobody Mon Jun 8 08:29:02 2026 Received: from out30-110.freemail.mail.aliyun.com (out30-110.freemail.mail.aliyun.com [115.124.30.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BAAF934B662; Sun, 31 May 2026 09:36:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.110 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220223; cv=none; b=ZKggAv1c19Fm04GZ045R68/7QGPQd+gGWv+ixIxcF835OJyVQgA4l7JwKsxxt6P8diZAhDK3OLODV41DL9zrbGphHrkJdiGfqwFn9gcoe0LcuenTymkB9Y0A6bljAVhKJDuYv70GC7ncuJn4OvhCaQAoUvUJPoPzn+5011yeZpw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220223; c=relaxed/simple; bh=oJIqP1iyO7MaCKG7ZLHM01HjVuoZVSrjdEg57/lFwQk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r7xQyO2KYzYrdwdYYzS5cfgwvWak4X0bDOSYerdQBDx1clHcWUAfh5VDUhPiXOk5dDC1N9FMw4FrhTlYf3edF/H5FWP4YGQuGuYAT9MIFrK6FN3p/JZmlVl//OB802Mo61pBGGhGLsYizbouFvQZT2dgazNNkpbs+R5HDaSKcYE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=ILl+5KXJ; arc=none smtp.client-ip=115.124.30.110 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="ILl+5KXJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220212; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=fMFLtmgtJGc7Xa/wXUQPOkhxPbCISpIgLbRDfLPPgtk=; b=ILl+5KXJeARUGICHCCSs+/rnMf5NSg0I53n1XPke+Q170+jv/vK5DVS1xrK04c/3GNpHrBc7jACuCT4P0C+CHxPBUaDhJivgCA0WB4lH1CKVtL0B1/sK4Y33SXAmz9ZehdsNaN+qCHBxmaHzcTmxIg497jQ3pP2s+01oZXsVL5s= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R191e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033045098064;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVpg_1780220210; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVpg_1780220210 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:50 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 4/9] iommu/arm-smmu: implement iova_to_phys_length Date: Sun, 31 May 2026 17:36:32 +0800 Message-ID: <20260531093637.3893199-5-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate ARM SMMU drivers to implement iova_to_phys_length, calling ops->iova_to_phys_length on the io-pgtable layer to get both phys and PTE page size. Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 10 +++++++--- drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c | 2 +- drivers/iommu/arm/arm-smmu/arm-smmu.c | 13 ++++++++----- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 11 +++++++---- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/ar= m/arm-smmu-v3/arm-smmu-v3.c index e8d7dbe495f0..c9f356c75bc5 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -4069,14 +4069,18 @@ static void arm_smmu_iotlb_sync(struct iommu_domain= *domain, } =20 static phys_addr_t -arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) +arm_smmu_iova_to_phys_length(struct iommu_domain *domain, dma_addr_t iova, + size_t *mapped_length) { struct io_pgtable_ops *ops =3D to_smmu_domain(domain)->pgtbl_ops; =20 + if (mapped_length) + *mapped_length =3D 0; + if (!ops) return 0; =20 - return ops->iova_to_phys(ops, iova); + return ops->iova_to_phys_length(ops, iova, mapped_length); } =20 static struct platform_driver arm_smmu_driver; @@ -4396,7 +4400,7 @@ static const struct iommu_ops arm_smmu_ops =3D { .unmap_pages =3D arm_smmu_unmap_pages, .flush_iotlb_all =3D arm_smmu_flush_iotlb_all, .iotlb_sync =3D arm_smmu_iotlb_sync, - .iova_to_phys =3D arm_smmu_iova_to_phys, + .iova_to_phys_length =3D arm_smmu_iova_to_phys_length, .free =3D arm_smmu_domain_free_paging, } }; diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c b/drivers/iom= mu/arm/arm-smmu/arm-smmu-qcom-debug.c index 65e0ef6539fe..4fd01341157f 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c @@ -415,7 +415,7 @@ irqreturn_t qcom_smmu_context_fault(int irq, void *dev) return IRQ_HANDLED; } =20 - phys_soft =3D ops->iova_to_phys(ops, cfi.iova); + phys_soft =3D ops->iova_to_phys_length(ops, cfi.iova, NULL); =20 tmp =3D report_iommu_fault(&smmu_domain->domain, NULL, cfi.iova, cfi.fsynr & ARM_SMMU_CB_FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_= READ); diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-= smmu/arm-smmu.c index 0bd21d206eb3..e29e0ea12f24 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1366,7 +1366,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct = iommu_domain *domain, "iova to phys timed out on %pad. Falling back to software table walk.\n= ", &iova); arm_smmu_rpm_put(smmu); - return ops->iova_to_phys(ops, iova); + return ops->iova_to_phys_length(ops, iova, NULL); } =20 phys =3D arm_smmu_cb_readq(smmu, idx, ARM_SMMU_CB_PAR); @@ -1384,12 +1384,15 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struc= t iommu_domain *domain, return addr; } =20 -static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t arm_smmu_iova_to_phys_length(struct iommu_domain *domai= n, + dma_addr_t iova, size_t *mapped_length) { struct arm_smmu_domain *smmu_domain =3D to_smmu_domain(domain); struct io_pgtable_ops *ops =3D smmu_domain->pgtbl_ops; =20 + if (mapped_length) + *mapped_length =3D 0; + if (!ops) return 0; =20 @@ -1397,7 +1400,7 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu= _domain *domain, smmu_domain->stage =3D=3D ARM_SMMU_DOMAIN_S1) return arm_smmu_iova_to_phys_hard(domain, iova); =20 - return ops->iova_to_phys(ops, iova); + return ops->iova_to_phys_length(ops, iova, mapped_length); } =20 static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap) @@ -1652,7 +1655,7 @@ static const struct iommu_ops arm_smmu_ops =3D { .unmap_pages =3D arm_smmu_unmap_pages, .flush_iotlb_all =3D arm_smmu_flush_iotlb_all, .iotlb_sync =3D arm_smmu_iotlb_sync, - .iova_to_phys =3D arm_smmu_iova_to_phys, + .iova_to_phys_length =3D arm_smmu_iova_to_phys_length, .set_pgtable_quirks =3D arm_smmu_set_pgtable_quirks, .free =3D arm_smmu_domain_free, } diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/ar= m-smmu/qcom_iommu.c index a1e8cf29f594..08bb6fce992f 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -489,19 +489,22 @@ static void qcom_iommu_iotlb_sync(struct iommu_domain= *domain, qcom_iommu_flush_iotlb_all(domain); } =20 -static phys_addr_t qcom_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t qcom_iommu_iova_to_phys_length(struct iommu_domain *dom= ain, + dma_addr_t iova, size_t *mapped_length) { phys_addr_t ret; unsigned long flags; struct qcom_iommu_domain *qcom_domain =3D to_qcom_iommu_domain(domain); struct io_pgtable_ops *ops =3D qcom_domain->pgtbl_ops; =20 + if (mapped_length) + *mapped_length =3D 0; + if (!ops) return 0; =20 spin_lock_irqsave(&qcom_domain->pgtbl_lock, flags); - ret =3D ops->iova_to_phys(ops, iova); + ret =3D ops->iova_to_phys_length(ops, iova, mapped_length); spin_unlock_irqrestore(&qcom_domain->pgtbl_lock, flags); =20 return ret; @@ -602,7 +605,7 @@ static const struct iommu_ops qcom_iommu_ops =3D { .unmap_pages =3D qcom_iommu_unmap, .flush_iotlb_all =3D qcom_iommu_flush_iotlb_all, .iotlb_sync =3D qcom_iommu_iotlb_sync, - .iova_to_phys =3D qcom_iommu_iova_to_phys, + .iova_to_phys_length =3D qcom_iommu_iova_to_phys_length, .free =3D qcom_iommu_domain_free, } }; --=20 2.43.7 From nobody Mon Jun 8 08:29:02 2026 Received: from out30-132.freemail.mail.aliyun.com (out30-132.freemail.mail.aliyun.com [115.124.30.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8F9934DCC8; Sun, 31 May 2026 09:37:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.132 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220230; cv=none; b=LMTrc36l35cDvsuHfR36RE2TwVNkwGon9hTYGwt6hkSzT4223DobVJyNTYupQPG8ekGVElRuNCxqlukVICRY1Vgkw6RuyKlJIKMNzLzve2guDFG3QdlaoPs/A34SDlGqO6w+xDkeyOF3pOofA/8LgqkoXz7kCpikLGe/tbI/Lc8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220230; c=relaxed/simple; bh=dpZfE/1w5bMY1F/GliYe4MvlNQ04qZxnTIF0/TWqsuE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I+spdP0aJe7SP3AWxmR81RPilq/INMkn80xSJVMnvdmrapqrhiUqwG1FiEXQrREApl8lsZ++XNFFRxOqWD4FwF52eBdXEuFL8RZsDUA13izhnsSTcSNjh6dFzQitmUjb+KnVJwECg7ZdGJ7Q3FlPek/C6FuH0mtTE8/mXuieDEE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=SYhrY8WR; arc=none smtp.client-ip=115.124.30.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="SYhrY8WR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220213; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=I124MUpdjyzqPwiXiO9Q5adcwpM3fxbXILO13MSKRkI=; b=SYhrY8WRXlNfSKkAkVNs7LPlhUmqR2iwa/jDSI+NAqdf9xQhG+QPUPRHeMq4Ka1WNul2RhzFGjYg6Rk2rDisowNbHM+PyZ+mHl7xlcy5ThfmavIruiwwapwXbuH6CbLUlu/hRB/B/fGKJ0TqHBRNoi/RII+Ej0UFY+7Wagpd5Ls= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R691e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033037009110;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVpy_1780220211; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVpy_1780220211 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:51 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 5/9] iommu: apple-dart/ipmmu/mtk_iommu implement iova_to_phys_length Date: Sun, 31 May 2026 17:36:33 +0800 Message-ID: <20260531093637.3893199-6-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate remaining io-pgtable user drivers to implement iova_to_phys_length, passing through mapped_length from io-pgtable. Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/iommu/apple-dart.c | 11 +++++++---- drivers/iommu/ipmmu-vmsa.c | 12 ++++++++---- drivers/iommu/mtk_iommu.c | 12 ++++++++---- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c index 17bdadb6b504..6f78bd28cee7 100644 --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@ -528,16 +528,19 @@ static int apple_dart_iotlb_sync_map(struct iommu_dom= ain *domain, return 0; } =20 -static phys_addr_t apple_dart_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t apple_dart_iova_to_phys_length(struct iommu_domain *dom= ain, + dma_addr_t iova, size_t *mapped_length) { struct apple_dart_domain *dart_domain =3D to_dart_domain(domain); struct io_pgtable_ops *ops =3D dart_domain->pgtbl_ops; =20 + if (mapped_length) + *mapped_length =3D 0; + if (!ops) return 0; =20 - return ops->iova_to_phys(ops, iova); + return ops->iova_to_phys_length(ops, iova, mapped_length); } =20 static int apple_dart_map_pages(struct iommu_domain *domain, unsigned long= iova, @@ -1018,7 +1021,7 @@ static const struct iommu_ops apple_dart_iommu_ops = =3D { .flush_iotlb_all =3D apple_dart_flush_iotlb_all, .iotlb_sync =3D apple_dart_iotlb_sync, .iotlb_sync_map =3D apple_dart_iotlb_sync_map, - .iova_to_phys =3D apple_dart_iova_to_phys, + .iova_to_phys_length =3D apple_dart_iova_to_phys_length, .free =3D apple_dart_domain_free, } }; diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 9386b752dea2..a1b659ddbdb5 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -699,14 +699,18 @@ static void ipmmu_iotlb_sync(struct iommu_domain *io_= domain, ipmmu_flush_iotlb_all(io_domain); } =20 -static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain, - dma_addr_t iova) +static phys_addr_t ipmmu_iova_to_phys_length(struct iommu_domain *io_domai= n, + dma_addr_t iova, size_t *mapped_length) { struct ipmmu_vmsa_domain *domain =3D to_vmsa_domain(io_domain); =20 + if (mapped_length) + *mapped_length =3D 0; + /* TODO: Is locking needed ? */ =20 - return domain->iop->iova_to_phys(domain->iop, iova); + return domain->iop->iova_to_phys_length(domain->iop, iova, + mapped_length); } =20 static int ipmmu_init_platform_device(struct device *dev, @@ -892,7 +896,7 @@ static const struct iommu_ops ipmmu_ops =3D { .unmap_pages =3D ipmmu_unmap, .flush_iotlb_all =3D ipmmu_flush_iotlb_all, .iotlb_sync =3D ipmmu_iotlb_sync, - .iova_to_phys =3D ipmmu_iova_to_phys, + .iova_to_phys_length =3D ipmmu_iova_to_phys_length, .free =3D ipmmu_domain_free, } }; diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 2be990c108de..214cab76e853 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -858,13 +858,17 @@ static int mtk_iommu_sync_map(struct iommu_domain *do= main, unsigned long iova, return 0; } =20 -static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t mtk_iommu_iova_to_phys_length(struct iommu_domain *doma= in, + dma_addr_t iova, size_t *mapped_length) { struct mtk_iommu_domain *dom =3D to_mtk_domain(domain); phys_addr_t pa; =20 - pa =3D dom->iop->iova_to_phys(dom->iop, iova); + if (mapped_length) + *mapped_length =3D 0; + + pa =3D dom->iop->iova_to_phys_length(dom->iop, iova, mapped_length); + if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) && dom->bank->parent_data->enable_4GB && pa >=3D MTK_IOMMU_4GB_MODE_REMAP_BASE) @@ -1070,7 +1074,7 @@ static const struct iommu_ops mtk_iommu_ops =3D { .flush_iotlb_all =3D mtk_iommu_flush_iotlb_all, .iotlb_sync =3D mtk_iommu_iotlb_sync, .iotlb_sync_map =3D mtk_iommu_sync_map, - .iova_to_phys =3D mtk_iommu_iova_to_phys, + .iova_to_phys_length =3D mtk_iommu_iova_to_phys_length, .free =3D mtk_iommu_domain_free, } }; --=20 2.43.7 From nobody Mon Jun 8 08:29:02 2026 Received: from out30-118.freemail.mail.aliyun.com (out30-118.freemail.mail.aliyun.com [115.124.30.118]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5B1B35675A; Sun, 31 May 2026 09:37:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.118 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220232; cv=none; b=F4CyP8c7n9sGDkHFhYQ5Uvn2zNabEqFMz++LXj19NrJs0d+6rzwsL2VQbzrUNO2h54lBBcQW7AodUXZcT9ebrx2QFSaIM9CF4Oq3hD9wK75dsMabEZWUv0bE+6bCxBRu+8gooHCR7m8o72KmohCeNXXMTFq65+xwla+ZLOcyXv8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220232; c=relaxed/simple; bh=TKNB+9iI7xo4tROo/8/zH66Q+gxg3Pk4X/g6VCnPfEk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ExdVHLIKah8taLPl75zfWeUktC3PobVV420FUPZRnjiRCl8cxkG3X1+RnVf+7D+oYsVdh2XmX5OVv1iPerGr1Xvrau2oYzNnfYU8yJKiWJQWAxzh7MHav8G+mS+FVF1NY6AI8HDCOHAz2COA58s1BAxdY4eFxeqz8qd4pPElxo8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=CiClcOTJ; arc=none smtp.client-ip=115.124.30.118 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="CiClcOTJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220214; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=kmQF0o5wICayDWeUP6+TxHOXn7wIJf+lrD/CiJCO3J0=; b=CiClcOTJsXIz8FkMwx4xaNpYJnvgxQlFyociOZ9kYXBb7zoxd/HUNVLApD0TOiLqV7JTH6U0+J+qC5Pdb9omRvtHSA01FNkzf4rjB03Ritw9LS7StDkYouu7urLsRHfAiL5vDs3YPBLo4U/7p7+lPwd6CNPHWExriYxkIi8+Crw= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R911e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033045098064;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVqJ_1780220212; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVqJ_1780220212 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:52 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 6/9] iommu: direct page-table drivers implement iova_to_phys_length Date: Sun, 31 May 2026 17:36:34 +0800 Message-ID: <20260531093637.3893199-7-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement iova_to_phys_length for all IOMMU drivers with direct page tables. Each returns the actual PTE mapping size. Also fix mtk_iommu_v1 pre-existing bug: add page offset to PA. Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/iommu/exynos-iommu.c | 21 ++++++++++++++++----- drivers/iommu/fsl_pamu_domain.c | 26 +++++++++++++++++++++++--- drivers/iommu/msm_iommu.c | 25 +++++++++++++++++++------ drivers/iommu/mtk_iommu_v1.c | 15 +++++++++++++-- drivers/iommu/omap-iommu.c | 32 +++++++++++++++++++++++--------- drivers/iommu/rockchip-iommu.c | 11 ++++++++--- drivers/iommu/s390-iommu.c | 15 +++++++++++---- drivers/iommu/sprd-iommu.c | 13 ++++++++++--- drivers/iommu/sun50i-iommu.c | 13 ++++++++++--- drivers/iommu/tegra-smmu.c | 12 +++++++++--- drivers/iommu/virtio-iommu.c | 13 ++++++++++--- 11 files changed, 152 insertions(+), 44 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 874d05f4b396..00ab813ed436 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -1372,27 +1372,38 @@ static size_t exynos_iommu_unmap(struct iommu_domai= n *iommu_domain, return 0; } =20 -static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_do= main, - dma_addr_t iova) +static phys_addr_t exynos_iommu_iova_to_phys_length(struct iommu_domain *i= ommu_domain, + dma_addr_t iova, + size_t *mapped_length) { struct exynos_iommu_domain *domain =3D to_exynos_domain(iommu_domain); sysmmu_pte_t *entry; unsigned long flags; phys_addr_t phys =3D 0; =20 + if (mapped_length) + *mapped_length =3D 0; + spin_lock_irqsave(&domain->pgtablelock, flags); =20 entry =3D section_entry(domain->pgtable, iova); =20 if (lv1ent_section(entry)) { phys =3D section_phys(entry) + section_offs(iova); + if (mapped_length) + *mapped_length =3D SECT_SIZE; } else if (lv1ent_page(entry)) { entry =3D page_entry(entry, iova); =20 - if (lv2ent_large(entry)) + if (lv2ent_large(entry)) { phys =3D lpage_phys(entry) + lpage_offs(iova); - else if (lv2ent_small(entry)) + if (mapped_length) + *mapped_length =3D LPAGE_SIZE; + } else if (lv2ent_small(entry)) { phys =3D spage_phys(entry) + spage_offs(iova); + if (mapped_length) + *mapped_length =3D SPAGE_SIZE; + } } =20 spin_unlock_irqrestore(&domain->pgtablelock, flags); @@ -1484,7 +1495,7 @@ static const struct iommu_ops exynos_iommu_ops =3D { .attach_dev =3D exynos_iommu_attach_device, .map_pages =3D exynos_iommu_map, .unmap_pages =3D exynos_iommu_unmap, - .iova_to_phys =3D exynos_iommu_iova_to_phys, + .iova_to_phys_length =3D exynos_iommu_iova_to_phys_length, .free =3D exynos_iommu_domain_free, } }; diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domai= n.c index 9664ef9840d2..48a072074b56 100644 --- a/drivers/iommu/fsl_pamu_domain.c +++ b/drivers/iommu/fsl_pamu_domain.c @@ -169,12 +169,32 @@ static void attach_device(struct fsl_dma_domain *dma_= domain, int liodn, struct d spin_unlock_irqrestore(&device_domain_lock, flags); } =20 -static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t fsl_pamu_iova_to_phys_length(struct iommu_domain *domai= n, + dma_addr_t iova, + size_t *mapped_length) { + if (mapped_length) + *mapped_length =3D 0; + if (iova < domain->geometry.aperture_start || iova > domain->geometry.aperture_end) return 0; + + /* + * PAMU configures exactly one Primary PAACE entry per LIODN with the + * Multi-Window (MW) bit cleared and ATM =3D PAACE_ATM_WINDOW_XLATE, + * WBAL/TWBAL =3D 0. That is, every LIODN is backed by a single hardware + * mapping window of fixed size (1ULL << 36, i.e. 64GB, see + * pamu_config_ppaace()) performing an identity translation. The driver + * does not split this window into SPAACE sub-windows, so the entire + * aperture is one PAACE "PTE" entry. Return that single entry's size + * as mapped_length, matching the iova_to_phys_length contract that + * mapped_length reports the full size of the mapping entry which + * covers iova (not the remaining bytes from iova to its end). + */ + if (mapped_length) + *mapped_length =3D 1ULL << 36; + return iova; } =20 @@ -435,7 +455,7 @@ static const struct iommu_ops fsl_pamu_ops =3D { .device_group =3D fsl_pamu_device_group, .default_domain_ops =3D &(const struct iommu_domain_ops) { .attach_dev =3D fsl_pamu_attach_device, - .iova_to_phys =3D fsl_pamu_iova_to_phys, + .iova_to_phys_length =3D fsl_pamu_iova_to_phys_length, .free =3D fsl_pamu_domain_free, } }; diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 0ad5ff431d5b..f36fdbf8076f 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -523,8 +523,9 @@ static size_t msm_iommu_unmap(struct iommu_domain *doma= in, unsigned long iova, return ret; } =20 -static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t va) +static phys_addr_t msm_iommu_iova_to_phys_length(struct iommu_domain *doma= in, + dma_addr_t va, + size_t *mapped_length) { struct msm_priv *priv; struct msm_iommu_dev *iommu; @@ -533,6 +534,9 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_= domain *domain, unsigned long flags; phys_addr_t ret =3D 0; =20 + if (mapped_length) + *mapped_length =3D 0; + spin_lock_irqsave(&msm_iommu_lock, flags); =20 priv =3D to_msm_priv(domain); @@ -558,13 +562,22 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iomm= u_domain *domain, par =3D GET_PAR(iommu->base, master->num); =20 /* We are dealing with a supersection */ - if (GET_NOFAULT_SS(iommu->base, master->num)) + if (GET_NOFAULT_SS(iommu->base, master->num)) { ret =3D (par & 0xFF000000) | (va & 0x00FFFFFF); - else /* Upper 20 bits from PAR, lower 12 from VA */ + if (mapped_length) + *mapped_length =3D SZ_16M; + } else { + /* Upper 20 bits from PAR, lower 12 from VA */ ret =3D (par & 0xFFFFF000) | (va & 0x00000FFF); + if (mapped_length) + *mapped_length =3D SZ_4K; + } =20 - if (GET_FAULT(iommu->base, master->num)) + if (GET_FAULT(iommu->base, master->num)) { ret =3D 0; + if (mapped_length) + *mapped_length =3D 0; + } =20 __disable_clocks(iommu); fail: @@ -706,7 +719,7 @@ static struct iommu_ops msm_iommu_ops =3D { */ .iotlb_sync =3D NULL, .iotlb_sync_map =3D msm_iommu_sync_map, - .iova_to_phys =3D msm_iommu_iova_to_phys, + .iova_to_phys_length =3D msm_iommu_iova_to_phys_length, .free =3D msm_iommu_domain_free, } }; diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index ac97dd2868d4..a451de7d669e 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -393,17 +393,28 @@ static size_t mtk_iommu_v1_unmap(struct iommu_domain = *domain, unsigned long iova return size; } =20 -static phys_addr_t mtk_iommu_v1_iova_to_phys(struct iommu_domain *domain, = dma_addr_t iova) +static phys_addr_t mtk_iommu_v1_iova_to_phys_length(struct iommu_domain *d= omain, + dma_addr_t iova, + size_t *mapped_length) { struct mtk_iommu_v1_domain *dom =3D to_mtk_domain(domain); unsigned long flags; phys_addr_t pa; =20 + if (mapped_length) + *mapped_length =3D 0; + spin_lock_irqsave(&dom->pgtlock, flags); pa =3D *(dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT)); pa =3D pa & (~(MT2701_IOMMU_PAGE_SIZE - 1)); spin_unlock_irqrestore(&dom->pgtlock, flags); =20 + if (pa) { + pa |=3D (iova & (MT2701_IOMMU_PAGE_SIZE - 1)); + if (mapped_length) + *mapped_length =3D MT2701_IOMMU_PAGE_SIZE; + } + return pa; } =20 @@ -590,7 +601,7 @@ static const struct iommu_ops mtk_iommu_v1_ops =3D { .attach_dev =3D mtk_iommu_v1_attach_device, .map_pages =3D mtk_iommu_v1_map, .unmap_pages =3D mtk_iommu_v1_unmap, - .iova_to_phys =3D mtk_iommu_v1_iova_to_phys, + .iova_to_phys_length =3D mtk_iommu_v1_iova_to_phys_length, .free =3D mtk_iommu_v1_domain_free, } }; diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 8231d7d6bb6a..91daa69decc9 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1592,8 +1592,9 @@ static void omap_iommu_domain_free(struct iommu_domai= n *domain) kfree(omap_domain); } =20 -static phys_addr_t omap_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t da) +static phys_addr_t omap_iommu_iova_to_phys_length(struct iommu_domain *dom= ain, + dma_addr_t da, + size_t *mapped_length) { struct omap_iommu_domain *omap_domain =3D to_omap_domain(domain); struct omap_iommu_device *iommu =3D omap_domain->iommus; @@ -1602,6 +1603,9 @@ static phys_addr_t omap_iommu_iova_to_phys(struct iom= mu_domain *domain, u32 *pgd, *pte; phys_addr_t ret =3D 0; =20 + if (mapped_length) + *mapped_length =3D 0; + /* * all the iommus within the domain will have identical programming, * so perform the lookup using just the first iommu @@ -1609,21 +1613,31 @@ static phys_addr_t omap_iommu_iova_to_phys(struct i= ommu_domain *domain, iopgtable_lookup_entry(oiommu, da, &pgd, &pte); =20 if (pte) { - if (iopte_is_small(*pte)) + if (iopte_is_small(*pte)) { ret =3D omap_iommu_translate(*pte, da, IOPTE_MASK); - else if (iopte_is_large(*pte)) + if (ret && mapped_length) + *mapped_length =3D IOPTE_SIZE; + } else if (iopte_is_large(*pte)) { ret =3D omap_iommu_translate(*pte, da, IOLARGE_MASK); - else + if (ret && mapped_length) + *mapped_length =3D IOLARGE_SIZE; + } else { dev_err(dev, "bogus pte 0x%x, da 0x%llx", *pte, (unsigned long long)da); + } } else { - if (iopgd_is_section(*pgd)) + if (iopgd_is_section(*pgd)) { ret =3D omap_iommu_translate(*pgd, da, IOSECTION_MASK); - else if (iopgd_is_super(*pgd)) + if (ret && mapped_length) + *mapped_length =3D IOSECTION_SIZE; + } else if (iopgd_is_super(*pgd)) { ret =3D omap_iommu_translate(*pgd, da, IOSUPER_MASK); - else + if (ret && mapped_length) + *mapped_length =3D IOSUPER_SIZE; + } else { dev_err(dev, "bogus pgd 0x%x, da 0x%llx", *pgd, (unsigned long long)da); + } } =20 return ret; @@ -1723,7 +1737,7 @@ static const struct iommu_ops omap_iommu_ops =3D { .attach_dev =3D omap_iommu_attach_dev, .map_pages =3D omap_iommu_map, .unmap_pages =3D omap_iommu_unmap, - .iova_to_phys =3D omap_iommu_iova_to_phys, + .iova_to_phys_length =3D omap_iommu_iova_to_phys_length, .free =3D omap_iommu_domain_free, } }; diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 0013cf196c57..dad3ff38fe2c 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -648,8 +648,8 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id) return ret; } =20 -static phys_addr_t rk_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t rk_iommu_iova_to_phys_length(struct iommu_domain *domai= n, + dma_addr_t iova, size_t *mapped_length) { struct rk_iommu_domain *rk_domain =3D to_rk_domain(domain); unsigned long flags; @@ -657,6 +657,9 @@ static phys_addr_t rk_iommu_iova_to_phys(struct iommu_d= omain *domain, u32 dte, pte; u32 *page_table; =20 + if (mapped_length) + *mapped_length =3D 0; + spin_lock_irqsave(&rk_domain->dt_lock, flags); =20 dte =3D rk_domain->dt[rk_iova_dte_index(iova)]; @@ -670,6 +673,8 @@ static phys_addr_t rk_iommu_iova_to_phys(struct iommu_d= omain *domain, goto out; =20 phys =3D rk_ops->pt_address(pte) + rk_iova_page_offset(iova); + if (mapped_length) + *mapped_length =3D SPAGE_SIZE; out: spin_unlock_irqrestore(&rk_domain->dt_lock, flags); =20 @@ -1187,7 +1192,7 @@ static const struct iommu_ops rk_iommu_ops =3D { .attach_dev =3D rk_iommu_attach_device, .map_pages =3D rk_iommu_map, .unmap_pages =3D rk_iommu_unmap, - .iova_to_phys =3D rk_iommu_iova_to_phys, + .iova_to_phys_length =3D rk_iommu_iova_to_phys_length, .free =3D rk_iommu_domain_free, } }; diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c index f148f559ac56..8df98aceb5f7 100644 --- a/drivers/iommu/s390-iommu.c +++ b/drivers/iommu/s390-iommu.c @@ -986,8 +986,9 @@ static unsigned long *get_rto_from_iova(struct s390_dom= ain *domain, } } =20 -static phys_addr_t s390_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t s390_iommu_iova_to_phys_length(struct iommu_domain *dom= ain, + dma_addr_t iova, + size_t *mapped_length) { struct s390_domain *s390_domain =3D to_s390_domain(domain); unsigned long *rto, *sto, *pto; @@ -995,6 +996,9 @@ static phys_addr_t s390_iommu_iova_to_phys(struct iommu= _domain *domain, unsigned int rtx, sx, px; phys_addr_t phys =3D 0; =20 + if (mapped_length) + *mapped_length =3D 0; + if (iova < domain->geometry.aperture_start || iova > domain->geometry.aperture_end) return 0; @@ -1014,8 +1018,11 @@ static phys_addr_t s390_iommu_iova_to_phys(struct io= mmu_domain *domain, if (reg_entry_isvalid(ste)) { pto =3D get_st_pto(ste); pte =3D READ_ONCE(pto[px]); - if (pt_entry_isvalid(pte)) + if (pt_entry_isvalid(pte)) { phys =3D pte & ZPCI_PTE_ADDR_MASK; + if (mapped_length) + *mapped_length =3D SZ_4K; + } } } =20 @@ -1183,7 +1190,7 @@ static struct iommu_domain blocking_domain =3D { .flush_iotlb_all =3D s390_iommu_flush_iotlb_all, \ .iotlb_sync =3D s390_iommu_iotlb_sync, \ .iotlb_sync_map =3D s390_iommu_iotlb_sync_map, \ - .iova_to_phys =3D s390_iommu_iova_to_phys, \ + .iova_to_phys_length =3D s390_iommu_iova_to_phys_length, \ .free =3D s390_domain_free, \ } =20 diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c index c1a34445d244..da14574a6430 100644 --- a/drivers/iommu/sprd-iommu.c +++ b/drivers/iommu/sprd-iommu.c @@ -366,8 +366,9 @@ static void sprd_iommu_sync(struct iommu_domain *domain, sprd_iommu_sync_map(domain, 0, 0); } =20 -static phys_addr_t sprd_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t sprd_iommu_iova_to_phys_length(struct iommu_domain *dom= ain, + dma_addr_t iova, + size_t *mapped_length) { struct sprd_iommu_domain *dom =3D to_sprd_domain(domain); unsigned long flags; @@ -375,6 +376,9 @@ static phys_addr_t sprd_iommu_iova_to_phys(struct iommu= _domain *domain, unsigned long start =3D domain->geometry.aperture_start; unsigned long end =3D domain->geometry.aperture_end; =20 + if (mapped_length) + *mapped_length =3D 0; + if (WARN_ON(iova < start || iova > end)) return 0; =20 @@ -383,6 +387,9 @@ static phys_addr_t sprd_iommu_iova_to_phys(struct iommu= _domain *domain, pa =3D (pa << SPRD_IOMMU_PAGE_SHIFT) + ((iova - start) & (SPRD_IOMMU_PAGE= _SIZE - 1)); spin_unlock_irqrestore(&dom->pgtlock, flags); =20 + if (pa && mapped_length) + *mapped_length =3D SPRD_IOMMU_PAGE_SIZE; + return pa; } =20 @@ -420,7 +427,7 @@ static const struct iommu_ops sprd_iommu_ops =3D { .unmap_pages =3D sprd_iommu_unmap, .iotlb_sync_map =3D sprd_iommu_sync_map, .iotlb_sync =3D sprd_iommu_sync, - .iova_to_phys =3D sprd_iommu_iova_to_phys, + .iova_to_phys_length =3D sprd_iommu_iova_to_phys_length, .free =3D sprd_iommu_domain_free, } }; diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c index be3f1ce696ba..66c354baaca1 100644 --- a/drivers/iommu/sun50i-iommu.c +++ b/drivers/iommu/sun50i-iommu.c @@ -659,14 +659,18 @@ static size_t sun50i_iommu_unmap(struct iommu_domain = *domain, unsigned long iova return SZ_4K; } =20 -static phys_addr_t sun50i_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t sun50i_iommu_iova_to_phys_length(struct iommu_domain *d= omain, + dma_addr_t iova, + size_t *mapped_length) { struct sun50i_iommu_domain *sun50i_domain =3D to_sun50i_domain(domain); phys_addr_t pt_phys; u32 *page_table; u32 dte, pte; =20 + if (mapped_length) + *mapped_length =3D 0; + dte =3D sun50i_domain->dt[sun50i_iova_get_dte_index(iova)]; if (!sun50i_dte_is_pt_valid(dte)) return 0; @@ -677,6 +681,9 @@ static phys_addr_t sun50i_iommu_iova_to_phys(struct iom= mu_domain *domain, if (!sun50i_pte_is_page_valid(pte)) return 0; =20 + if (mapped_length) + *mapped_length =3D SZ_4K; + return sun50i_pte_get_page_address(pte) + sun50i_iova_get_page_offset(iova); } @@ -857,7 +864,7 @@ static const struct iommu_ops sun50i_iommu_ops =3D { .flush_iotlb_all =3D sun50i_iommu_flush_iotlb_all, .iotlb_sync_map =3D sun50i_iommu_iotlb_sync_map, .iotlb_sync =3D sun50i_iommu_iotlb_sync, - .iova_to_phys =3D sun50i_iommu_iova_to_phys, + .iova_to_phys_length =3D sun50i_iommu_iova_to_phys_length, .map_pages =3D sun50i_iommu_map, .unmap_pages =3D sun50i_iommu_unmap, .free =3D sun50i_iommu_domain_free, diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 67e7a7b925f0..c2545d577fdc 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -803,20 +803,26 @@ static size_t tegra_smmu_unmap(struct iommu_domain *d= omain, unsigned long iova, return size; } =20 -static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t tegra_smmu_iova_to_phys_length(struct iommu_domain *dom= ain, + dma_addr_t iova, size_t *mapped_length) { struct tegra_smmu_as *as =3D to_smmu_as(domain); unsigned long pfn; dma_addr_t pte_dma; u32 *pte; =20 + if (mapped_length) + *mapped_length =3D 0; + pte =3D tegra_smmu_pte_lookup(as, iova, &pte_dma); if (!pte || !*pte) return 0; =20 pfn =3D *pte & as->smmu->pfn_mask; =20 + if (mapped_length) + *mapped_length =3D SZ_4K; + return SMMU_PFN_PHYS(pfn) + SMMU_OFFSET_IN_PAGE(iova); } =20 @@ -1007,7 +1013,7 @@ static const struct iommu_ops tegra_smmu_ops =3D { .attach_dev =3D tegra_smmu_attach_dev, .map_pages =3D tegra_smmu_map, .unmap_pages =3D tegra_smmu_unmap, - .iova_to_phys =3D tegra_smmu_iova_to_phys, + .iova_to_phys_length =3D tegra_smmu_iova_to_phys_length, .free =3D tegra_smmu_domain_free, } }; diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 587fc13197f1..80c9c06a1380 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -912,8 +912,9 @@ static size_t viommu_unmap_pages(struct iommu_domain *d= omain, unsigned long iova return ret ? 0 : unmapped; } =20 -static phys_addr_t viommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) +static phys_addr_t viommu_iova_to_phys_length(struct iommu_domain *domain, + dma_addr_t iova, + size_t *mapped_length) { u64 paddr =3D 0; unsigned long flags; @@ -921,11 +922,17 @@ static phys_addr_t viommu_iova_to_phys(struct iommu_d= omain *domain, struct interval_tree_node *node; struct viommu_domain *vdomain =3D to_viommu_domain(domain); =20 + if (mapped_length) + *mapped_length =3D 0; + spin_lock_irqsave(&vdomain->mappings_lock, flags); node =3D interval_tree_iter_first(&vdomain->mappings, iova, iova); if (node) { mapping =3D container_of(node, struct viommu_mapping, iova); paddr =3D mapping->paddr + (iova - mapping->iova.start); + if (mapped_length) + *mapped_length =3D mapping->iova.last - + mapping->iova.start + 1; } spin_unlock_irqrestore(&vdomain->mappings_lock, flags); =20 @@ -1102,7 +1109,7 @@ static const struct iommu_ops viommu_ops =3D { .attach_dev =3D viommu_attach_dev, .map_pages =3D viommu_map_pages, .unmap_pages =3D viommu_unmap_pages, - .iova_to_phys =3D viommu_iova_to_phys, + .iova_to_phys_length =3D viommu_iova_to_phys_length, .flush_iotlb_all =3D viommu_flush_iotlb_all, .iotlb_sync =3D viommu_iotlb_sync, .iotlb_sync_map =3D viommu_iotlb_sync_map, --=20 2.43.7 From nobody Mon Jun 8 08:29:02 2026 Received: from out30-132.freemail.mail.aliyun.com (out30-132.freemail.mail.aliyun.com [115.124.30.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 805752727E2; Sun, 31 May 2026 09:37:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.132 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220227; cv=none; b=YbhLEQ3Gf8h0szLqdNRE0uxZgKx2qcrhFD2fcoCdxV0C8d2uvPfGE30ARhPKnCGgUNkpwFgOq6bVwm4eVPjScB68cy63JTGTz86Xue2M1yppDQLcqggz4AmdM0DTW3L/4Vt0qQ5nxkn6D9ZsQsRzqchwH4fW6LIpOqaEEnET1Ww= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220227; c=relaxed/simple; bh=0JAXqK7FOWEyWPbACJIWWGnQ5ymY7eTri1sGoNrWSFs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Iblpj9BnGbzoqtlZeAxbHFRLrPUE5DXf8o+kxwVR4wGgS+CoSmEsnNpAFAlHqvpz8Dsy9P7+EUp5IAI0XlMpZaB3BVq41rV79gX/3evR43o2hE5O3ZO6QJXWsJVEgHsJjw5fielpclxbY3bXPlsQ55u/jBwuO1n5gOfJEfwwnsY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=HMmCPgb/; arc=none smtp.client-ip=115.124.30.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="HMmCPgb/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220216; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=9GYfPp1sU1WLVHRudSCocbfBnHaSnI+DlgtBGa8tOy0=; b=HMmCPgb/BaDhDk6BYc+IlkEEP3KbeYwKPv0j6na0sLeb9RsKLKMPhU0WMdLIGO0CtnE/6cSTXIpiMD4AHuOZqRBWVPFReL7lmmY36FCcb/Zr2fus/nUV7D2MW/xeOFoMZnLkaxrHEvUg9R4vZPU7E4GFMPZ6PAAITFz+ofShcfs= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R131e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033032089153;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVqi_1780220213; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVqi_1780220213 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:53 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 7/9] vfio/iommufd: use iova_to_phys_length for efficient unmap Date: Sun, 31 May 2026 17:36:35 +0800 Message-ID: <20260531093637.3893199-8-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use iommu_iova_to_phys_length() to get PTE page size, allowing traversal by actual mapping granularity instead of PAGE_SIZE steps. Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/iommu/iommufd/pages.c | 71 ++++++++++++++++++++++++++------ drivers/iommu/iommufd/selftest.c | 2 +- drivers/vfio/vfio_iommu_type1.c | 24 +++++++++-- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c index 9bdb2945afe1..d67e564035b4 100644 --- a/drivers/iommu/iommufd/pages.c +++ b/drivers/iommu/iommufd/pages.c @@ -417,17 +417,42 @@ static void batch_from_domain(struct pfn_batch *batch, if (start_index =3D=3D iopt_area_index(area)) page_offset =3D area->page_offset; while (start_index <=3D last_index) { + size_t pgsize; + unsigned long npages; + unsigned long i; + /* - * This is pretty slow, it would be nice to get the page size - * back from the driver, or have the driver directly fill the - * batch. + * Use iova_to_phys_length to get both the physical address + * and the PTE page size in a single page table walk, allowing + * us to skip ahead by the contiguous region size instead of + * walking the page tables for every PAGE_SIZE step. */ - phys =3D iommu_iova_to_phys(domain, iova) - page_offset; - if (!batch_add_pfn(batch, PHYS_PFN(phys))) - return; - iova +=3D PAGE_SIZE - page_offset; + phys =3D iommu_iova_to_phys_length(domain, iova, &pgsize) - + page_offset; + if (!pgsize || pgsize < PAGE_SIZE) + pgsize =3D PAGE_SIZE; + + /* + * Calculate contiguous pages within this PTE from our + * position. phys points to the page-aligned start (backed + * up by page_offset), so pages available =3D bytes from phys + * to PTE end divided by PAGE_SIZE. + */ + npages =3D (pgsize - (iova & (pgsize - 1)) + page_offset) / + PAGE_SIZE; + npages =3D min_t(unsigned long, npages, + last_index - start_index + 1); + if (!npages) + npages =3D 1; + + for (i =3D 0; i < npages; i++) { + if (!batch_add_pfn(batch, PHYS_PFN(phys) + i)) + return; + } + + iova +=3D npages * PAGE_SIZE - page_offset; page_offset =3D 0; - start_index++; + start_index +=3D npages; } } =20 @@ -445,11 +470,33 @@ static struct page **raw_pages_from_domain(struct iom= mu_domain *domain, if (start_index =3D=3D iopt_area_index(area)) page_offset =3D area->page_offset; while (start_index <=3D last_index) { - phys =3D iommu_iova_to_phys(domain, iova) - page_offset; - *(out_pages++) =3D pfn_to_page(PHYS_PFN(phys)); - iova +=3D PAGE_SIZE - page_offset; + size_t pgsize; + unsigned long npages; + unsigned long i; + + /* + * Resolve the PTE page size together with the physical + * address so we can fill multiple struct page pointers per + * page table walk when the IOMMU uses large pages. + */ + phys =3D iommu_iova_to_phys_length(domain, iova, &pgsize) - + page_offset; + if (!pgsize || pgsize < PAGE_SIZE) + pgsize =3D PAGE_SIZE; + + npages =3D (pgsize - (iova & (pgsize - 1)) + page_offset) / + PAGE_SIZE; + npages =3D min_t(unsigned long, npages, + last_index - start_index + 1); + if (!npages) + npages =3D 1; + + for (i =3D 0; i < npages; i++) + *(out_pages++) =3D pfn_to_page(PHYS_PFN(phys) + i); + + iova +=3D npages * PAGE_SIZE - page_offset; page_offset =3D 0; - start_index++; + start_index +=3D npages; } return out_pages; } diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selft= est.c index af07c642a526..4b9c3ffc9523 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -1214,7 +1214,7 @@ static int iommufd_test_md_check_pa(struct iommufd_uc= md *ucmd, pfn =3D page_to_pfn(pages[0]); put_page(pages[0]); =20 - io_phys =3D mock->domain.ops->iova_to_phys(&mock->domain, iova); + io_phys =3D iommu_iova_to_phys(&mock->domain, iova); if (io_phys !=3D pfn * PAGE_SIZE + ((uintptr_t)uptr % PAGE_SIZE)) { rc =3D -EINVAL; diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type= 1.c index c8151ba54de3..393f9e8f1511 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1177,25 +1177,41 @@ static long vfio_unmap_unpin(struct vfio_iommu *iom= mu, struct vfio_dma *dma, =20 iommu_iotlb_gather_init(&iotlb_gather); while (pos < dma->size) { - size_t unmapped, len; + size_t unmapped, len, pgsize; phys_addr_t phys, next; dma_addr_t iova =3D dma->iova + pos; =20 - phys =3D iommu_iova_to_phys(domain->domain, iova); + /* Single page table walk returns both phys and PTE size */ + phys =3D iommu_iova_to_phys_length(domain->domain, iova, + &pgsize); if (WARN_ON(!phys)) { pos +=3D PAGE_SIZE; continue; } + if (!pgsize || pgsize < PAGE_SIZE) + pgsize =3D PAGE_SIZE; =20 /* * To optimize for fewer iommu_unmap() calls, each of which * may require hardware cache flushing, try to find the * largest contiguous physical memory chunk to unmap. + * + * Calculate remaining contiguous bytes within this PTE from + * our position, then try to join following physically + * contiguous PTEs. */ - for (len =3D PAGE_SIZE; pos + len < dma->size; len +=3D PAGE_SIZE) { - next =3D iommu_iova_to_phys(domain->domain, iova + len); + len =3D pgsize - (iova & (pgsize - 1)); + for (; pos + len < dma->size; ) { + size_t next_pgsize; + + next =3D iommu_iova_to_phys_length(domain->domain, + iova + len, + &next_pgsize); if (next !=3D phys + len) break; + if (!next_pgsize || next_pgsize < PAGE_SIZE) + next_pgsize =3D PAGE_SIZE; + len +=3D next_pgsize; } =20 /* --=20 2.43.7 From nobody Mon Jun 8 08:29:02 2026 Received: from out30-110.freemail.mail.aliyun.com (out30-110.freemail.mail.aliyun.com [115.124.30.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 68A2C35C180; Sun, 31 May 2026 09:37:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.110 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220227; cv=none; b=NAhlHy7bEvblgPRskaC4AhWwCNKZPPKkS4TDWvveJEYRyUczcmC+qKLcsG2HNJEEXxPHFnXZG9aOEyxQ6V6nXLlCU+N7Cxn1h6M0+ur6qFnxEtc2/cfV1wmcF7hKAEorgCUh2ITRI4Vu0A8KEdoOOzg+94rmgduD/4DTfK+b9NE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220227; c=relaxed/simple; bh=pKmgUI48sTB5iHvAnPZ7bLYJ+0ijpTEuXSqdVUx5LiM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R2YfUctlUrcbNiLc1z0jercZ6b1Bm5Uhz6OnPxPtoc0DMeMMCAChLqH1lY4ep3k7rwqXSjSg9O4iTODTVJmndnUIfEGaS3kzmJhQSSsU1dudWcaHwAGMl7kxse70yD68ZkOj3rv8/ixnZul4mptYqpLRneAO0WUlVnKBTTD9DNY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=YLiQQQac; arc=none smtp.client-ip=115.124.30.110 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="YLiQQQac" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220217; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=RpB/ofZVI8aYfi4QDy17DKJQX9fsUwx+3+WYjwsW/4E=; b=YLiQQQacHXyjwkvKe4+Og+po2eZ1293UunyFYQWtuqPOersDZHMUL/Vwoa2oWkSIUQ6awoFpefjDMggV6D1MpzLHEOELRoRSMJoKx67xBZNX6JmGNMvsF6I58GjG73M6Wf4cPi9qI4WmCIPv7bxX/Y5dRFrUABC7RTA0TYm12Vs= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R121e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033045098064;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVr2_1780220214; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVr2_1780220214 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:54 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 8/9] drm/gpu, iommu/io-pgtable: switch to iova_to_phys_length Date: Sun, 31 May 2026 17:36:36 +0800 Message-ID: <20260531093637.3893199-9-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate remaining callers of io_pgtable_ops.iova_to_phys: - panthor_mmu: use ops->iova_to_phys_length(ops, iova, NULL) - panfrost_mmu: same - io-pgtable selftests: use iova_to_phys_length with NULL Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +- drivers/gpu/drm/panthor/panthor_mmu.c | 2 +- drivers/iommu/io-pgtable-arm-selftests.c | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panf= rost/panfrost_mmu.c index 4a3162c3b659..b7c420eb76ec 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -514,7 +514,7 @@ void panfrost_mmu_unmap(struct panfrost_gem_mapping *ma= pping) =20 if (bo->is_heap) pgcount =3D 1; - if (!bo->is_heap || ops->iova_to_phys(ops, iova)) { + if (!bo->is_heap || ops->iova_to_phys_length(ops, iova, NULL)) { unmapped_page =3D ops->unmap_pages(ops, iova, pgsize, pgcount, NULL); WARN_ON(unmapped_page !=3D pgsize * pgcount); } diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/pantho= r/panthor_mmu.c index 75d98dad7b1d..05bc7ec95931 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -903,7 +903,7 @@ static void panthor_vm_unmap_pages(struct panthor_vm *v= m, u64 iova, u64 size) * are out-of-sync. This is not supposed to happen, hence the * above WARN_ON(). */ - while (!ops->iova_to_phys(ops, iova + unmapped_sz) && + while (!ops->iova_to_phys_length(ops, iova + unmapped_sz, NULL) && unmapped_sz < pgsize * pgcount) unmapped_sz +=3D SZ_4K; =20 diff --git a/drivers/iommu/io-pgtable-arm-selftests.c b/drivers/iommu/io-pg= table-arm-selftests.c index 334e70350924..d1d0529f711d 100644 --- a/drivers/iommu/io-pgtable-arm-selftests.c +++ b/drivers/iommu/io-pgtable-arm-selftests.c @@ -72,13 +72,13 @@ static int arm_lpae_run_tests(struct kunit *test, struc= t io_pgtable_cfg *cfg) * Initial sanity checks. * Empty page tables shouldn't provide any translations. */ - if (ops->iova_to_phys(ops, 42)) + if (ops->iova_to_phys_length(ops, 42, NULL)) return __FAIL(test, i); =20 - if (ops->iova_to_phys(ops, SZ_1G + 42)) + if (ops->iova_to_phys_length(ops, SZ_1G + 42, NULL)) return __FAIL(test, i); =20 - if (ops->iova_to_phys(ops, SZ_2G + 42)) + if (ops->iova_to_phys_length(ops, SZ_2G + 42, NULL)) return __FAIL(test, i); =20 /* @@ -100,7 +100,7 @@ static int arm_lpae_run_tests(struct kunit *test, struc= t io_pgtable_cfg *cfg) GFP_KERNEL, &mapped)) return __FAIL(test, i); =20 - if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) + if (ops->iova_to_phys_length(ops, iova + 42, NULL) !=3D (iova + 42)) return __FAIL(test, i); =20 iova +=3D SZ_1G; @@ -114,7 +114,7 @@ static int arm_lpae_run_tests(struct kunit *test, struc= t io_pgtable_cfg *cfg) if (ops->unmap_pages(ops, iova, size, 1, NULL) !=3D size) return __FAIL(test, i); =20 - if (ops->iova_to_phys(ops, iova + 42)) + if (ops->iova_to_phys_length(ops, iova + 42, NULL)) return __FAIL(test, i); =20 /* Remap full block */ @@ -122,7 +122,7 @@ static int arm_lpae_run_tests(struct kunit *test, struc= t io_pgtable_cfg *cfg) IOMMU_WRITE, GFP_KERNEL, &mapped)) return __FAIL(test, i); =20 - if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) + if (ops->iova_to_phys_length(ops, iova + 42, NULL) !=3D (iova + 42)) return __FAIL(test, i); =20 iova +=3D SZ_1G; --=20 2.43.7 From nobody Mon Jun 8 08:29:02 2026 Received: from out199-6.us.a.mail.aliyun.com (out199-6.us.a.mail.aliyun.com [47.90.199.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B2AD357D19; Sun, 31 May 2026 09:37:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=47.90.199.6 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220236; cv=none; b=H79l0X534kBfaJJsBKdh6J3ttFKChHZ30JJRQMGw+VFDtYq6CctQx0QOVMXrE4r2Np7az2IcDqdxBxyeVOb388tLJHjdssSS4GzkIoTZmzyunbOqZWnQQ7rdcxORyTXGqjNoSOWGzy5rANxgrNZYJ2qHhDOi+/4uoxmGVu0wN3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780220236; c=relaxed/simple; bh=xRalzbcpLDZ7+7bYboe0Stt7HU7h6x+ZVecxZJ0LG6A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fBYOlL9Nqmpt/YAp+OoHm6rQhh+rytE7Ls+OaAEV1gwCiWewunl1+cSBrZmKE5OMg/xJx6sVScj0gX5vmFOGNCX08BK6F4yJ3NYoEGBPc3dqKq77YkdnX1Angue71FiKVDXvAkQcXWNeK8svbOEJE4SYevjR9ZCh8GYxXvBw8rM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=MmiFBQOR; arc=none smtp.client-ip=47.90.199.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="MmiFBQOR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1780220217; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=4/Z+ZPm/plftxIVQEjNwZFqBQEqg7EIjfcS2GaMAQFU=; b=MmiFBQORJe2csb7MQbPTKnXb+GtbgaX++0RtqBihtwDrUFJktrng7jjAi38u2fkz/ZKC4FIlrZfmGkH50Mh+5sCD6Afu9SELDV1BHzJbe19ehEBEAjmTutofc22yRZ6I515ai8U0fdk4mJtTtzfuVYsLKt83dUP72A2naTzbqt8= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R331e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033032089153;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=27;SR=0;TI=SMTPD_---0X3tRVrQ_1780220215; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X3tRVrQ_1780220215 cluster:ay36) by smtp.aliyun-inc.com; Sun, 31 May 2026 17:36:55 +0800 From: Guanghui Feng To: boris.brezillon@collabora.com, robh@kernel.org, steven.price@arm.com, adrian.larumbe@collabora.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, liviu.dudau@arm.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, alex@shazbot.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, jgg@ziepe.ca, kevin.tian@intel.com, baolu.lu@linux.intel.com, suravee.suthikulpanit@amd.com, dwmw2@infradead.org Cc: xlpang@linux.alibaba.com, oliver.yang@linux.alibaba.com, shiyu.zsq@linux.alibaba.com, wei.guo.simon@linux.alibaba.com Subject: [PATCH 9/9] iommu: remove deprecated iova_to_phys from domain_ops and io_pgtable_ops Date: Sun, 31 May 2026 17:36:37 +0800 Message-ID: <20260531093637.3893199-10-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> References: <20260529115116.GR2487554@ziepe.ca> <20260531093637.3893199-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that all drivers implement iova_to_phys_length and all callers have migrated, remove the deprecated interfaces: - Remove .iova_to_phys from struct iommu_domain_ops - Remove .iova_to_phys from struct io_pgtable_ops - Remove fallback in iommu_iova_to_phys_length() - Make iommu_iova_to_phys() a thin wrapper - Remove old wrapper functions from io-pgtable implementations Signed-off-by: Guanghui Feng Acked-by: Shiqiang Zhang Acked-by: Simon Guo --- drivers/iommu/io-pgtable-arm-v7s.c | 11 ----------- drivers/iommu/io-pgtable-arm.c | 11 ----------- drivers/iommu/io-pgtable-dart.c | 11 ----------- drivers/iommu/iommu.c | 4 ---- include/linux/io-pgtable.h | 3 --- include/linux/iommu.h | 3 --- 6 files changed, 43 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-= arm-v7s.c index 54e8cc673eb6..00c09710b01b 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c @@ -641,16 +641,6 @@ static size_t arm_v7s_unmap_pages(struct io_pgtable_op= s *ops, unsigned long iova return unmapped; } =20 -static phys_addr_t arm_v7s_iova_to_phys_length(struct io_pgtable_ops *ops, - unsigned long iova, - size_t *mapped_length); - -static phys_addr_t arm_v7s_iova_to_phys(struct io_pgtable_ops *ops, - unsigned long iova) -{ - return arm_v7s_iova_to_phys_length(ops, iova, NULL); -} - static phys_addr_t arm_v7s_iova_to_phys_length(struct io_pgtable_ops *ops, unsigned long iova, size_t *mapped_length) @@ -730,7 +720,6 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct = io_pgtable_cfg *cfg, data->iop.ops =3D (struct io_pgtable_ops) { .map_pages =3D arm_v7s_map_pages, .unmap_pages =3D arm_v7s_unmap_pages, - .iova_to_phys =3D arm_v7s_iova_to_phys, .iova_to_phys_length =3D arm_v7s_iova_to_phys_length, }; =20 diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index e2ea84669fbf..c7419f812e79 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -731,16 +731,6 @@ static int visit_iova_to_phys(struct io_pgtable_walk_d= ata *walk_data, int lvl, return 0; } =20 -static phys_addr_t arm_lpae_iova_to_phys_length(struct io_pgtable_ops *ops, - unsigned long iova, - size_t *mapped_length); - -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops, - unsigned long iova) -{ - return arm_lpae_iova_to_phys_length(ops, iova, NULL); -} - static phys_addr_t arm_lpae_iova_to_phys_length(struct io_pgtable_ops *ops, unsigned long iova, size_t *mapped_length) @@ -963,7 +953,6 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg) data->iop.ops =3D (struct io_pgtable_ops) { .map_pages =3D arm_lpae_map_pages, .unmap_pages =3D arm_lpae_unmap_pages, - .iova_to_phys =3D arm_lpae_iova_to_phys, .iova_to_phys_length =3D arm_lpae_iova_to_phys_length, .read_and_clear_dirty =3D arm_lpae_read_and_clear_dirty, .pgtable_walk =3D arm_lpae_pgtable_walk, diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dar= t.c index fa250f5d16ed..f71c04a4c15e 100644 --- a/drivers/iommu/io-pgtable-dart.c +++ b/drivers/iommu/io-pgtable-dart.c @@ -333,16 +333,6 @@ static size_t dart_unmap_pages(struct io_pgtable_ops *= ops, unsigned long iova, return i * pgsize; } =20 -static phys_addr_t dart_iova_to_phys_length(struct io_pgtable_ops *ops, - unsigned long iova, - size_t *mapped_length); - -static phys_addr_t dart_iova_to_phys(struct io_pgtable_ops *ops, - unsigned long iova) -{ - return dart_iova_to_phys_length(ops, iova, NULL); -} - static phys_addr_t dart_iova_to_phys_length(struct io_pgtable_ops *ops, unsigned long iova, size_t *mapped_length) @@ -414,7 +404,6 @@ dart_alloc_pgtable(struct io_pgtable_cfg *cfg) data->iop.ops =3D (struct io_pgtable_ops) { .map_pages =3D dart_map_pages, .unmap_pages =3D dart_unmap_pages, - .iova_to_phys =3D dart_iova_to_phys, .iova_to_phys_length =3D dart_iova_to_phys_length, }; =20 diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 43323229a1df..df56635de39d 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2573,10 +2573,6 @@ phys_addr_t iommu_iova_to_phys_length(struct iommu_d= omain *domain, return domain->ops->iova_to_phys_length(domain, iova, mapped_length); =20 - /* Fallback to legacy iova_to_phys without length info */ - if (domain->ops->iova_to_phys) - return domain->ops->iova_to_phys(domain, iova); - return 0; } EXPORT_SYMBOL_GPL(iommu_iova_to_phys_length); diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 42bcdd309b88..c595f5b51e61 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -202,7 +202,6 @@ struct arm_lpae_io_pgtable_walk_data { * * @map_pages: Map a physically contiguous range of pages of the same s= ize. * @unmap_pages: Unmap a range of virtually contiguous pages of the same = size. - * @iova_to_phys: Translate iova to physical address. * @iova_to_phys_length: Translate iova to physical address and return the * remaining mapped length from iova to the end of the * mapping entry via @mapped_length. If @mapped_length is @@ -222,8 +221,6 @@ struct io_pgtable_ops { size_t (*unmap_pages)(struct io_pgtable_ops *ops, unsigned long iova, size_t pgsize, size_t pgcount, struct iommu_iotlb_gather *gather); - phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops, - unsigned long iova); phys_addr_t (*iova_to_phys_length)(struct io_pgtable_ops *ops, unsigned long iova, size_t *mapped_length); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19da84c2922c..ca585647180b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -746,7 +746,6 @@ struct iommu_ops { * array->entry_num to report the number of handled * invalidation requests. The driver data structure * must be defined in include/uapi/linux/iommufd.h - * @iova_to_phys: translate iova to physical address * @iova_to_phys_length: translate iova to physical address and additional= ly * return the page size of the PTE mapping at @iova * through @mapped_length. @@ -777,8 +776,6 @@ struct iommu_domain_ops { int (*cache_invalidate_user)(struct iommu_domain *domain, struct iommu_user_data_array *array); =20 - phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, - dma_addr_t iova); phys_addr_t (*iova_to_phys_length)(struct iommu_domain *domain, dma_addr_t iova, size_t *mapped_length); --=20 2.43.7