Commit e9d36c07 authored by Nicolin Chen's avatar Nicolin Chen Committed by Jason Gunthorpe
Browse files

iommu: Add iommu_copy_struct_from_user helper

Wrap up the data type/pointer/len sanity and a copy_struct_from_user call
for iommu drivers to copy driver specific data via struct iommu_user_data.
And expect it to be used in the domain_alloc_user op for example.

Link: https://lore.kernel.org/r/20231026043938.63898-9-yi.l.liu@intel.com


Signed-off-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Co-developed-by: default avatarYi Liu <yi.l.liu@intel.com>
Signed-off-by: default avatarYi Liu <yi.l.liu@intel.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent bd529dbb
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -280,6 +280,46 @@ struct iommu_user_data {
	size_t len;
};

/**
 * __iommu_copy_struct_from_user - Copy iommu driver specific user space data
 * @dst_data: Pointer to an iommu driver specific user data that is defined in
 *            include/uapi/linux/iommufd.h
 * @src_data: Pointer to a struct iommu_user_data for user space data info
 * @data_type: The data type of the @dst_data. Must match with @src_data.type
 * @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(
	void *dst_data, const struct iommu_user_data *src_data,
	unsigned int data_type, size_t data_len, size_t min_len)
{
	if (src_data->type != data_type)
		return -EINVAL;
	if (WARN_ON(!dst_data || !src_data))
		return -EINVAL;
	if (src_data->len < min_len || data_len < src_data->len)
		return -EINVAL;
	return copy_struct_from_user(dst_data, data_len, src_data->uptr,
				     src_data->len);
}

/**
 * iommu_copy_struct_from_user - Copy iommu driver specific user space data
 * @kdst: Pointer to an iommu driver specific user data that is defined in
 *        include/uapi/linux/iommufd.h
 * @user_data: Pointer to a struct iommu_user_data for user space data info
 * @data_type: The data type of the @kdst. Must match with @user_data->type
 * @min_last: The last memember of the data structure @kdst points in the
 *            initial version.
 * Return 0 for success, otherwise -error.
 */
#define iommu_copy_struct_from_user(kdst, user_data, data_type, min_last) \
	__iommu_copy_struct_from_user(kdst, user_data, data_type,         \
				      sizeof(*kdst),                      \
				      offsetofend(typeof(*kdst), min_last))

/**
 * struct iommu_ops - iommu ops and capabilities
 * @capable: check capability