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

Signed-off-by: Guanghui Feng <[email protected]>
---
 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

Reply via email to