[PATCH v2 18/30] iommu/s390: implement iova_to_phys_length

From: Guanghui Feng

Date: Tue Jun 02 2026 - 06:57:42 EST


Implement iova_to_phys_length for s390 IOMMU driver,
returning the actual PTE mapping size.

Signed-off-by: Guanghui Feng <guanghuifeng@xxxxxxxxxxxxxxxxx>
---
drivers/iommu/s390-iommu.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index f148f559ac56..b12ed389e1bd 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -986,22 +986,26 @@ static unsigned long *get_rto_from_iova(struct s390_domain *domain,
}
}

-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 *domain,
+ dma_addr_t iova,
+ size_t *mapped_length)
{
struct s390_domain *s390_domain = to_s390_domain(domain);
unsigned long *rto, *sto, *pto;
unsigned long ste, pte, rte;
unsigned int rtx, sx, px;
- phys_addr_t phys = 0;
+ phys_addr_t phys = PHYS_ADDR_MAX;
+
+ if (mapped_length)
+ *mapped_length = 0;

if (iova < domain->geometry.aperture_start ||
iova > domain->geometry.aperture_end)
- return 0;
+ return PHYS_ADDR_MAX;

rto = get_rto_from_iova(s390_domain, iova);
if (!rto)
- return 0;
+ return PHYS_ADDR_MAX;

rtx = calc_rtx(iova);
sx = calc_sx(iova);
@@ -1014,8 +1018,11 @@ static phys_addr_t s390_iommu_iova_to_phys(struct iommu_domain *domain,
if (reg_entry_isvalid(ste)) {
pto = get_st_pto(ste);
pte = READ_ONCE(pto[px]);
- if (pt_entry_isvalid(pte))
+ if (pt_entry_isvalid(pte)) {
phys = pte & ZPCI_PTE_ADDR_MASK;
+ if (mapped_length)
+ *mapped_length = SZ_4K;
+ }
}
}

@@ -1183,7 +1190,7 @@ static struct iommu_domain blocking_domain = {
.flush_iotlb_all = s390_iommu_flush_iotlb_all, \
.iotlb_sync = s390_iommu_iotlb_sync, \
.iotlb_sync_map = s390_iommu_iotlb_sync_map, \
- .iova_to_phys = s390_iommu_iova_to_phys, \
+ .iova_to_phys_length = s390_iommu_iova_to_phys_length, \
.free = s390_domain_free, \
}

--
2.43.7