@@ -704,42 +704,6 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
704
704
data -> start_level , ptep );
705
705
}
706
706
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
-
743
707
struct io_pgtable_walk_data {
744
708
struct io_pgtable * iop ;
745
709
void * data ;
@@ -755,6 +719,41 @@ static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
755
719
arm_lpae_iopte * ptep ,
756
720
int lvl );
757
721
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
+
758
757
static int io_pgtable_visit (struct arm_lpae_io_pgtable * data ,
759
758
struct io_pgtable_walk_data * walk_data ,
760
759
arm_lpae_iopte * ptep , int lvl )
@@ -772,8 +771,9 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
772
771
return 0 ;
773
772
}
774
773
775
- if (WARN_ON ( !iopte_table (pte , lvl )))
774
+ if (!iopte_table (pte , lvl )) {
776
775
return - EINVAL ;
776
+ }
777
777
778
778
ptep = iopte_deref (pte , data );
779
779
return __arm_lpae_iopte_walk (data , walk_data , ptep , lvl + 1 );
0 commit comments