mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 02:31:27 +02:00
iommu: Add iommu_copy_struct_from_full_user_array helper
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. Link: https://patch.msgid.link/r/5cd773d9c26920c5807d232b21d415ea79172e49.1730836308.git.nicolinc@nvidia.com Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
54ce69e36c
commit
4f2e59ccb6
|
|
@ -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
|
* @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
|
* @min_last: The last member of the data structure @kdst points in the
|
||||||
* initial version.
|
* 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, \
|
#define iommu_copy_struct_from_user_array(kdst, user_array, data_type, index, \
|
||||||
min_last) \
|
min_last) \
|
||||||
|
|
@ -501,6 +503,50 @@ static inline int __iommu_copy_struct_from_user_array(
|
||||||
kdst, user_array, data_type, index, sizeof(*(kdst)), \
|
kdst, user_array, data_type, index, sizeof(*(kdst)), \
|
||||||
offsetofend(typeof(*(kdst)), min_last))
|
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
|
* struct iommu_ops - iommu ops and capabilities
|
||||||
* @capable: check capability
|
* @capable: check capability
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user