@@ -170,13 +170,18 @@ static void page_array_unpin_free(struct page_array *pa, struct vfio_device *vde
170
170
kfree (pa -> pa_iova );
171
171
}
172
172
173
- static bool page_array_iova_pinned (struct page_array * pa , unsigned long iova )
173
+ static bool page_array_iova_pinned (struct page_array * pa , u64 iova , u64 length )
174
174
{
175
+ u64 iova_pfn_start = iova >> PAGE_SHIFT ;
176
+ u64 iova_pfn_end = (iova + length - 1 ) >> PAGE_SHIFT ;
177
+ u64 pfn ;
175
178
int i ;
176
179
177
- for (i = 0 ; i < pa -> pa_nr ; i ++ )
178
- if (pa -> pa_iova [i ] == iova )
180
+ for (i = 0 ; i < pa -> pa_nr ; i ++ ) {
181
+ pfn = pa -> pa_iova [i ] >> PAGE_SHIFT ;
182
+ if (pfn >= iova_pfn_start && pfn <= iova_pfn_end )
179
183
return true;
184
+ }
180
185
181
186
return false;
182
187
}
@@ -899,11 +904,12 @@ void cp_update_scsw(struct channel_program *cp, union scsw *scsw)
899
904
* cp_iova_pinned() - check if an iova is pinned for a ccw chain.
900
905
* @cp: channel_program on which to perform the operation
901
906
* @iova: the iova to check
907
+ * @length: the length to check from @iova
902
908
*
903
909
* If the @iova is currently pinned for the ccw chain, return true;
904
910
* else return false.
905
911
*/
906
- bool cp_iova_pinned (struct channel_program * cp , u64 iova )
912
+ bool cp_iova_pinned (struct channel_program * cp , u64 iova , u64 length )
907
913
{
908
914
struct ccwchain * chain ;
909
915
int i ;
@@ -913,7 +919,7 @@ bool cp_iova_pinned(struct channel_program *cp, u64 iova)
913
919
914
920
list_for_each_entry (chain , & cp -> ccwchain_list , next ) {
915
921
for (i = 0 ; i < chain -> ch_len ; i ++ )
916
- if (page_array_iova_pinned (chain -> ch_pa + i , iova ))
922
+ if (page_array_iova_pinned (chain -> ch_pa + i , iova , length ))
917
923
return true;
918
924
}
919
925
0 commit comments