@@ -741,33 +741,33 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
741
741
}
742
742
743
743
struct io_pgtable_walk_data {
744
- struct iommu_dirty_bitmap * dirty ;
744
+ struct io_pgtable * iop ;
745
+ void * data ;
746
+ int (* visit )(struct io_pgtable_walk_data * walk_data , int lvl ,
747
+ arm_lpae_iopte * ptep , size_t size );
745
748
unsigned long flags ;
746
749
u64 addr ;
747
750
const u64 end ;
748
751
};
749
752
750
- static int __arm_lpae_iopte_walk_dirty (struct arm_lpae_io_pgtable * data ,
751
- struct io_pgtable_walk_data * walk_data ,
752
- arm_lpae_iopte * ptep ,
753
- int lvl );
753
+ static int __arm_lpae_iopte_walk (struct arm_lpae_io_pgtable * data ,
754
+ struct io_pgtable_walk_data * walk_data ,
755
+ arm_lpae_iopte * ptep ,
756
+ int lvl );
754
757
755
- static int io_pgtable_visit_dirty (struct arm_lpae_io_pgtable * data ,
756
- struct io_pgtable_walk_data * walk_data ,
757
- arm_lpae_iopte * ptep , int lvl )
758
+ static int io_pgtable_visit (struct arm_lpae_io_pgtable * data ,
759
+ struct io_pgtable_walk_data * walk_data ,
760
+ arm_lpae_iopte * ptep , int lvl )
758
761
{
759
762
struct io_pgtable * iop = & data -> iop ;
760
763
arm_lpae_iopte pte = READ_ONCE (* ptep );
761
764
762
- if (iopte_leaf (pte , lvl , iop -> fmt )) {
763
- size_t size = ARM_LPAE_BLOCK_SIZE (lvl , data );
765
+ size_t size = ARM_LPAE_BLOCK_SIZE (lvl , data );
766
+ int ret = walk_data -> visit (walk_data , lvl , ptep , size );
767
+ if (ret )
768
+ return ret ;
764
769
765
- if (iopte_writeable_dirty (pte )) {
766
- iommu_dirty_bitmap_record (walk_data -> dirty ,
767
- walk_data -> addr , size );
768
- if (!(walk_data -> flags & IOMMU_DIRTY_NO_CLEAR ))
769
- iopte_set_writeable_clean (ptep );
770
- }
770
+ if (iopte_leaf (pte , lvl , iop -> fmt )) {
771
771
walk_data -> addr += size ;
772
772
return 0 ;
773
773
}
@@ -776,13 +776,13 @@ static int io_pgtable_visit_dirty(struct arm_lpae_io_pgtable *data,
776
776
return - EINVAL ;
777
777
778
778
ptep = iopte_deref (pte , data );
779
- return __arm_lpae_iopte_walk_dirty (data , walk_data , ptep , lvl + 1 );
779
+ return __arm_lpae_iopte_walk (data , walk_data , ptep , lvl + 1 );
780
780
}
781
781
782
- static int __arm_lpae_iopte_walk_dirty (struct arm_lpae_io_pgtable * data ,
783
- struct io_pgtable_walk_data * walk_data ,
784
- arm_lpae_iopte * ptep ,
785
- int lvl )
782
+ static int __arm_lpae_iopte_walk (struct arm_lpae_io_pgtable * data ,
783
+ struct io_pgtable_walk_data * walk_data ,
784
+ arm_lpae_iopte * ptep ,
785
+ int lvl )
786
786
{
787
787
u32 idx ;
788
788
int max_entries , ret ;
@@ -797,14 +797,31 @@ static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
797
797
798
798
for (idx = ARM_LPAE_LVL_IDX (walk_data -> addr , lvl , data );
799
799
(idx < max_entries ) && (walk_data -> addr < walk_data -> end ); ++ idx ) {
800
- ret = io_pgtable_visit_dirty (data , walk_data , ptep + idx , lvl );
800
+ ret = io_pgtable_visit (data , walk_data , ptep + idx , lvl );
801
801
if (ret )
802
802
return ret ;
803
803
}
804
804
805
805
return 0 ;
806
806
}
807
807
808
+ static int visit_dirty (struct io_pgtable_walk_data * walk_data , int lvl ,
809
+ arm_lpae_iopte * ptep , size_t size )
810
+ {
811
+ struct iommu_dirty_bitmap * dirty = walk_data -> data ;
812
+
813
+ if (!iopte_leaf (* ptep , lvl , walk_data -> iop -> fmt ))
814
+ return 0 ;
815
+
816
+ if (iopte_writeable_dirty (* ptep )) {
817
+ iommu_dirty_bitmap_record (dirty , walk_data -> addr , size );
818
+ if (!(walk_data -> flags & IOMMU_DIRTY_NO_CLEAR ))
819
+ iopte_set_writeable_clean (ptep );
820
+ }
821
+
822
+ return 0 ;
823
+ }
824
+
808
825
static int arm_lpae_read_and_clear_dirty (struct io_pgtable_ops * ops ,
809
826
unsigned long iova , size_t size ,
810
827
unsigned long flags ,
@@ -813,7 +830,9 @@ static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
813
830
struct arm_lpae_io_pgtable * data = io_pgtable_ops_to_data (ops );
814
831
struct io_pgtable_cfg * cfg = & data -> iop .cfg ;
815
832
struct io_pgtable_walk_data walk_data = {
816
- .dirty = dirty ,
833
+ .iop = & data -> iop ,
834
+ .data = dirty ,
835
+ .visit = visit_dirty ,
817
836
.flags = flags ,
818
837
.addr = iova ,
819
838
.end = iova + size ,
@@ -828,7 +847,7 @@ static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
828
847
if (data -> iop .fmt != ARM_64_LPAE_S1 )
829
848
return - EINVAL ;
830
849
831
- return __arm_lpae_iopte_walk_dirty (data , & walk_data , ptep , lvl );
850
+ return __arm_lpae_iopte_walk (data , & walk_data , ptep , lvl );
832
851
}
833
852
834
853
static void arm_lpae_restrict_pgsizes (struct io_pgtable_cfg * cfg )
0 commit comments