Message ID | d22517338a5c2bbd4c1bd5569f4409412206e100.1729897278.git.nicolinc@nvidia.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | iommufd: Add vIOMMU infrastructure (Part-2: vDEVICE) | expand |
> From: Nicolin Chen <nicolinc@nvidia.com> > Sent: Saturday, October 26, 2024 7:51 AM > > From: Jason Gunthorpe <jgg@nvidia.com> > > The iommu_copy_struct_from_user_array helper can be used to copy a > single > entry from a user array which might not be efficient if the array is big. > > Add a new iommu_copy_struct_from_full_user_array to copy the entire user > array at once. Update the existing iommu_copy_struct_from_user_array > kdoc > accordingly. what about: iommu_copy_struct_from_user_array_single() iommu_copy_struct_from_user_array_full() ? > > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
On Tue, Oct 29, 2024 at 08:24:52AM +0000, Tian, Kevin wrote: > > From: Nicolin Chen <nicolinc@nvidia.com> > > Sent: Saturday, October 26, 2024 7:51 AM > > > > From: Jason Gunthorpe <jgg@nvidia.com> > > > > The iommu_copy_struct_from_user_array helper can be used to copy a > > single > > entry from a user array which might not be efficient if the array is big. > > > > Add a new iommu_copy_struct_from_full_user_array to copy the entire user > > array at once. Update the existing iommu_copy_struct_from_user_array > > kdoc > > accordingly. > > what about: > > iommu_copy_struct_from_user_array_single() > iommu_copy_struct_from_user_array_full() I am okay with that, yet might prefer that in a separate patch? As I am trying to reduce the number of changes in the series since we are likely merging three series at once :) Thanks Nicolin > > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> > > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> > > Reviewed-by: Kevin Tian <kevin.tian@intel.com>
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 14f24b5cd16f..3c3d5d0849d7 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -493,7 +493,9 @@ static inline int __iommu_copy_struct_from_user_array( * @index: Index to the location in the array to copy user data from * @min_last: The last member of the data structure @kdst points in the * initial version. - * Return 0 for success, otherwise -error. + * + * Copy a single entry from a user array. Return 0 for success, otherwise + * -error. */ #define iommu_copy_struct_from_user_array(kdst, user_array, data_type, index, \ min_last) \ @@ -501,6 +503,50 @@ static inline int __iommu_copy_struct_from_user_array( kdst, user_array, data_type, index, sizeof(*(kdst)), \ offsetofend(typeof(*(kdst)), min_last)) +/** + * iommu_copy_struct_from_full_user_array - Copy iommu driver specific user + * space data from an iommu_user_data_array + * @kdst: Pointer to an iommu driver specific user data that is defined in + * include/uapi/linux/iommufd.h + * @kdst_entry_size: sizeof(*kdst) + * @user_array: Pointer to a struct iommu_user_data_array for a user space + * array + * @data_type: The data type of the @kdst. Must match with @user_array->type + * + * Copy the entire user array. kdst must have room for kdst_entry_size * + * user_array->entry_num bytes. Return 0 for success, otherwise -error. + */ +static inline int +iommu_copy_struct_from_full_user_array(void *kdst, size_t kdst_entry_size, + struct iommu_user_data_array *user_array, + unsigned int data_type) +{ + unsigned int i; + int ret; + + if (user_array->type != data_type) + return -EINVAL; + if (!user_array->entry_num) + return -EINVAL; + if (likely(user_array->entry_len == kdst_entry_size)) { + if (copy_from_user(kdst, user_array->uptr, + user_array->entry_num * + user_array->entry_len)) + return -EFAULT; + } + + /* Copy item by item */ + for (i = 0; i != user_array->entry_num; i++) { + ret = copy_struct_from_user( + kdst + kdst_entry_size * i, kdst_entry_size, + user_array->uptr + user_array->entry_len * i, + user_array->entry_len); + if (ret) + return ret; + } + return 0; +} + /** * struct iommu_ops - iommu ops and capabilities * @capable: check capability