From: Rob Clark <[email protected]>

Re-use the generic pgtable walk path.

Signed-off-by: Rob Clark <[email protected]>
Reviewed-by: Mostafa Saleh <[email protected]>
---
 drivers/iommu/io-pgtable-arm.c | 74 +++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 7e9c0f8ae138..88b128c77893 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -712,42 +712,6 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops 
*ops, unsigned long iov
                                data->start_level, ptep);
 }
 
-static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
-                                        unsigned long iova)
-{
-       struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
-       arm_lpae_iopte pte, *ptep = data->pgd;
-       int lvl = data->start_level;
-
-       do {
-               /* Valid IOPTE pointer? */
-               if (!ptep)
-                       return 0;
-
-               /* Grab the IOPTE we're interested in */
-               ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
-               pte = READ_ONCE(*ptep);
-
-               /* Valid entry? */
-               if (!pte)
-                       return 0;
-
-               /* Leaf entry? */
-               if (iopte_leaf(pte, lvl, data->iop.fmt))
-                       goto found_translation;
-
-               /* Take it to the next level */
-               ptep = iopte_deref(pte, data);
-       } while (++lvl < ARM_LPAE_MAX_LEVELS);
-
-       /* Ran out of page tables to walk */
-       return 0;
-
-found_translation:
-       iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
-       return iopte_to_paddr(pte, data) | iova;
-}
-
 struct io_pgtable_walk_data {
        struct io_pgtable               *iop;
        void                            *data;
@@ -763,6 +727,41 @@ static int __arm_lpae_iopte_walk(struct 
arm_lpae_io_pgtable *data,
                                 arm_lpae_iopte *ptep,
                                 int lvl);
 
+struct iova_to_phys_data {
+       arm_lpae_iopte pte;
+       int lvl;
+};
+
+static int visit_iova_to_phys(struct io_pgtable_walk_data *walk_data, int lvl,
+                             arm_lpae_iopte *ptep, size_t size)
+{
+       struct iova_to_phys_data *data = walk_data->data;
+       data->pte = *ptep;
+       data->lvl = lvl;
+       return 0;
+}
+
+static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
+                                        unsigned long iova)
+{
+       struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+       struct iova_to_phys_data d;
+       struct io_pgtable_walk_data walk_data = {
+               .data = &d,
+               .visit = visit_iova_to_phys,
+               .addr = iova,
+               .end = iova + 1,
+       };
+       int ret;
+
+       ret = __arm_lpae_iopte_walk(data, &walk_data, data->pgd, 
data->start_level);
+       if (ret)
+               return 0;
+
+       iova &= (ARM_LPAE_BLOCK_SIZE(d.lvl, data) - 1);
+       return iopte_to_paddr(d.pte, data) | iova;
+}
+
 static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
                            struct io_pgtable_walk_data *walk_data,
                            arm_lpae_iopte *ptep, int lvl)
@@ -780,8 +779,9 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable 
*data,
                return 0;
        }
 
-       if (WARN_ON(!iopte_table(pte, lvl)))
+       if (!iopte_table(pte, lvl)) {
                return -EINVAL;
+       }
 
        ptep = iopte_deref(pte, data);
        return __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
-- 
2.47.1

Reply via email to