@@ -493,14 +493,60 @@ static inline int __iommu_copy_struct_from_user_array(
493
493
* @index: Index to the location in the array to copy user data from
494
494
* @min_last: The last member of the data structure @kdst points in the
495
495
* initial version.
496
- * Return 0 for success, otherwise -error.
496
+ *
497
+ * Copy a single entry from a user array. Return 0 for success, otherwise
498
+ * -error.
497
499
*/
498
500
#define iommu_copy_struct_from_user_array (kdst , user_array , data_type , index , \
499
501
min_last ) \
500
502
__iommu_copy_struct_from_user_array( \
501
503
kdst, user_array, data_type, index, sizeof(*(kdst)), \
502
504
offsetofend(typeof(*(kdst)), min_last))
503
505
506
+ /**
507
+ * iommu_copy_struct_from_full_user_array - Copy iommu driver specific user
508
+ * space data from an iommu_user_data_array
509
+ * @kdst: Pointer to an iommu driver specific user data that is defined in
510
+ * include/uapi/linux/iommufd.h
511
+ * @kdst_entry_size: sizeof(*kdst)
512
+ * @user_array: Pointer to a struct iommu_user_data_array for a user space
513
+ * array
514
+ * @data_type: The data type of the @kdst. Must match with @user_array->type
515
+ *
516
+ * Copy the entire user array. kdst must have room for kdst_entry_size *
517
+ * user_array->entry_num bytes. Return 0 for success, otherwise -error.
518
+ */
519
+ static inline int
520
+ iommu_copy_struct_from_full_user_array (void * kdst , size_t kdst_entry_size ,
521
+ struct iommu_user_data_array * user_array ,
522
+ unsigned int data_type )
523
+ {
524
+ unsigned int i ;
525
+ int ret ;
526
+
527
+ if (user_array -> type != data_type )
528
+ return - EINVAL ;
529
+ if (!user_array -> entry_num )
530
+ return - EINVAL ;
531
+ if (likely (user_array -> entry_len == kdst_entry_size )) {
532
+ if (copy_from_user (kdst , user_array -> uptr ,
533
+ user_array -> entry_num *
534
+ user_array -> entry_len ))
535
+ return - EFAULT ;
536
+ }
537
+
538
+ /* Copy item by item */
539
+ for (i = 0 ; i != user_array -> entry_num ; i ++ ) {
540
+ ret = copy_struct_from_user (
541
+ kdst + kdst_entry_size * i , kdst_entry_size ,
542
+ user_array -> uptr + user_array -> entry_len * i ,
543
+ user_array -> entry_len );
544
+ if (ret )
545
+ return ret ;
546
+ }
547
+ return 0 ;
548
+ }
549
+
504
550
/**
505
551
* struct iommu_ops - iommu ops and capabilities
506
552
* @capable: check capability
0 commit comments