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

iommu: Add iommu_copy_struct_to_user helper

Similar to the iommu_copy_struct_from_user helper receiving data from the
user space, add an iommu_copy_struct_to_user helper to report output data
back to the user space data pointer.

Link: https://patch.msgid.link/r/fa292c2a730aadd77085ec3a8272360c96eabb9c.1752126748.git.nicolinc@nvidia.com


Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarPranjal Shrivastava <praan@google.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Signed-off-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 4b57c057
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -558,6 +558,46 @@ iommu_copy_struct_from_full_user_array(void *kdst, size_t kdst_entry_size,
	return 0;
}

/**
 * __iommu_copy_struct_to_user - Report iommu driver specific user space data
 * @dst_data: Pointer to a struct iommu_user_data for user space data location
 * @src_data: Pointer to an iommu driver specific user data that is defined in
 *            include/uapi/linux/iommufd.h
 * @data_type: The data type of the @src_data. Must match with @dst_data.type
 * @data_len: Length of current user data structure, i.e. sizeof(struct _src)
 * @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_to_user(const struct iommu_user_data *dst_data,
			    void *src_data, unsigned int data_type,
			    size_t data_len, size_t min_len)
{
	if (WARN_ON(!dst_data || !src_data))
		return -EINVAL;
	if (dst_data->type != data_type)
		return -EINVAL;
	if (dst_data->len < min_len || data_len < dst_data->len)
		return -EINVAL;
	return copy_struct_to_user(dst_data->uptr, dst_data->len, src_data,
				   data_len, NULL);
}

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

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