Skip to content

Commit d9e589e

Browse files
robclarkwilldeacon
authored andcommitted
iommu/io-pgtable-arm: Re-use the pgtable walk for iova_to_phys
Re-use the generic pgtable walk path. Signed-off-by: Rob Clark <[email protected]> Reviewed-by: Mostafa Saleh <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 821500d commit d9e589e

File tree

1 file changed

+37
-37
lines changed

1 file changed

+37
-37
lines changed

drivers/iommu/io-pgtable-arm.c

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -704,42 +704,6 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
704704
data->start_level, ptep);
705705
}
706706

707-
static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
708-
unsigned long iova)
709-
{
710-
struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
711-
arm_lpae_iopte pte, *ptep = data->pgd;
712-
int lvl = data->start_level;
713-
714-
do {
715-
/* Valid IOPTE pointer? */
716-
if (!ptep)
717-
return 0;
718-
719-
/* Grab the IOPTE we're interested in */
720-
ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
721-
pte = READ_ONCE(*ptep);
722-
723-
/* Valid entry? */
724-
if (!pte)
725-
return 0;
726-
727-
/* Leaf entry? */
728-
if (iopte_leaf(pte, lvl, data->iop.fmt))
729-
goto found_translation;
730-
731-
/* Take it to the next level */
732-
ptep = iopte_deref(pte, data);
733-
} while (++lvl < ARM_LPAE_MAX_LEVELS);
734-
735-
/* Ran out of page tables to walk */
736-
return 0;
737-
738-
found_translation:
739-
iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
740-
return iopte_to_paddr(pte, data) | iova;
741-
}
742-
743707
struct io_pgtable_walk_data {
744708
struct io_pgtable *iop;
745709
void *data;
@@ -755,6 +719,41 @@ static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
755719
arm_lpae_iopte *ptep,
756720
int lvl);
757721

722+
struct iova_to_phys_data {
723+
arm_lpae_iopte pte;
724+
int lvl;
725+
};
726+
727+
static int visit_iova_to_phys(struct io_pgtable_walk_data *walk_data, int lvl,
728+
arm_lpae_iopte *ptep, size_t size)
729+
{
730+
struct iova_to_phys_data *data = walk_data->data;
731+
data->pte = *ptep;
732+
data->lvl = lvl;
733+
return 0;
734+
}
735+
736+
static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
737+
unsigned long iova)
738+
{
739+
struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
740+
struct iova_to_phys_data d;
741+
struct io_pgtable_walk_data walk_data = {
742+
.data = &d,
743+
.visit = visit_iova_to_phys,
744+
.addr = iova,
745+
.end = iova + 1,
746+
};
747+
int ret;
748+
749+
ret = __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
750+
if (ret)
751+
return 0;
752+
753+
iova &= (ARM_LPAE_BLOCK_SIZE(d.lvl, data) - 1);
754+
return iopte_to_paddr(d.pte, data) | iova;
755+
}
756+
758757
static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
759758
struct io_pgtable_walk_data *walk_data,
760759
arm_lpae_iopte *ptep, int lvl)
@@ -772,8 +771,9 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
772771
return 0;
773772
}
774773

775-
if (WARN_ON(!iopte_table(pte, lvl)))
774+
if (!iopte_table(pte, lvl)) {
776775
return -EINVAL;
776+
}
777777

778778
ptep = iopte_deref(pte, data);
779779
return __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);

0 commit comments

Comments
 (0)