iommu: Add iommu_copy_struct_from_user_array helper

Wrap up the data pointer/num sanity and __iommu_copy_struct_from_user()
call for iommu drivers to copy driver specific data at a specific location
in the struct iommu_user_data_array.

And expect it to be used in cache_invalidate_user ops for example.

Link: https://lore.kernel.org/r/20240111041015.47920-4-yi.l.liu@intel.com
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Co-developed-by: Yi Liu <yi.l.liu@intel.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Nicolin Chen 2024-01-10 20:10:10 -08:00 committed by Jason Gunthorpe
parent 8c6eabae38
commit 77785117f9

View File

@ -341,6 +341,57 @@ static inline int __iommu_copy_struct_from_user(
sizeof(*kdst), \
offsetofend(typeof(*kdst), min_last))
/**
* __iommu_copy_struct_from_user_array - Copy iommu driver specific user space
* data from an iommu_user_data_array
* @dst_data: Pointer to an iommu driver specific user data that is defined in
* include/uapi/linux/iommufd.h
* @src_array: Pointer to a struct iommu_user_data_array for a user space array
* @data_type: The data type of the @dst_data. Must match with @src_array.type
* @index: Index to the location in the array to copy user data from
* @data_len: Length of current user data structure, i.e. sizeof(struct _dst)
* @min_len: Initial length of user data structure for backward compatibility.
* This should be offsetofend using the last member in the user data
* struct that was initially added to include/uapi/linux/iommufd.h
*/
static inline int __iommu_copy_struct_from_user_array(
void *dst_data, const struct iommu_user_data_array *src_array,
unsigned int data_type, unsigned int index, size_t data_len,
size_t min_len)
{
struct iommu_user_data src_data;
if (WARN_ON(!src_array || index >= src_array->entry_num))
return -EINVAL;
if (!src_array->entry_num)
return -EINVAL;
src_data.uptr = src_array->uptr + src_array->entry_len * index;
src_data.len = src_array->entry_len;
src_data.type = src_array->type;
return __iommu_copy_struct_from_user(dst_data, &src_data, data_type,
data_len, min_len);
}
/**
* iommu_copy_struct_from_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
* @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
* @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.
*/
#define iommu_copy_struct_from_user_array(kdst, user_array, data_type, index, \
min_last) \
__iommu_copy_struct_from_user_array( \
kdst, user_array, data_type, index, sizeof(*(kdst)), \
offsetofend(typeof(*(kdst)), min_last))
/**
* struct iommu_ops - iommu ops and capabilities
* @capable: check capability