@@ -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-
743707struct 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+
758757static 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