iommu: Pass in parent domain with user_data to domain_alloc_user op
domain_alloc_user op already accepts user flags for domain allocation, add a parent domain pointer and a driver specific user data support as well. The user data would be tagged with a type for iommu drivers to add their own driver specific user data per hw_pagetable. Add a struct iommu_user_data as a bundle of data_ptr/data_len/type from an iommufd core uAPI structure. Make the user data opaque to the core, since a userspace driver must match the kernel driver. In the future, if drivers share some common parameter, there would be a generic parameter as well. Link: https://lore.kernel.org/r/20231026043938.63898-7-yi.l.liu@intel.com Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Co-developed-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
b5021cb264
commit
2bdabb8e82
@ -2219,12 +2219,15 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned int type)
|
||||
return domain;
|
||||
}
|
||||
|
||||
static struct iommu_domain *amd_iommu_domain_alloc_user(struct device *dev,
|
||||
u32 flags)
|
||||
static struct iommu_domain *
|
||||
amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
|
||||
struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data)
|
||||
|
||||
{
|
||||
unsigned int type = IOMMU_DOMAIN_UNMANAGED;
|
||||
|
||||
if (flags & ~IOMMU_HWPT_ALLOC_DIRTY_TRACKING)
|
||||
if ((flags & ~IOMMU_HWPT_ALLOC_DIRTY_TRACKING) || parent || user_data)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
return do_iommu_domain_alloc(type, dev, flags);
|
||||
|
@ -4076,7 +4076,9 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
|
||||
}
|
||||
|
||||
static struct iommu_domain *
|
||||
intel_iommu_domain_alloc_user(struct device *dev, u32 flags)
|
||||
intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
|
||||
struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data)
|
||||
{
|
||||
struct iommu_domain *domain;
|
||||
struct intel_iommu *iommu;
|
||||
@ -4086,6 +4088,9 @@ intel_iommu_domain_alloc_user(struct device *dev, u32 flags)
|
||||
(~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (parent || user_data)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
iommu = device_to_iommu(dev, NULL, NULL);
|
||||
if (!iommu)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
@ -108,7 +108,8 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
|
||||
hwpt_paging->ioas = ioas;
|
||||
|
||||
if (ops->domain_alloc_user) {
|
||||
hwpt->domain = ops->domain_alloc_user(idev->dev, flags);
|
||||
hwpt->domain =
|
||||
ops->domain_alloc_user(idev->dev, flags, NULL, NULL);
|
||||
if (IS_ERR(hwpt->domain)) {
|
||||
rc = PTR_ERR(hwpt->domain);
|
||||
hwpt->domain = NULL;
|
||||
|
@ -241,7 +241,9 @@ static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
|
||||
}
|
||||
|
||||
static struct iommu_domain *
|
||||
mock_domain_alloc_user(struct device *dev, u32 flags)
|
||||
mock_domain_alloc_user(struct device *dev, u32 flags,
|
||||
struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data)
|
||||
{
|
||||
struct mock_dev *mdev = container_of(dev, struct mock_dev, dev);
|
||||
struct iommu_domain *domain;
|
||||
@ -250,6 +252,9 @@ mock_domain_alloc_user(struct device *dev, u32 flags)
|
||||
(~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (parent || user_data)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if ((flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING) &&
|
||||
(mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
@ -265,6 +265,21 @@ struct iommu_dirty_ops {
|
||||
struct iommu_dirty_bitmap *dirty);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iommu_user_data - iommu driver specific user space data info
|
||||
* @type: The data type of the user buffer
|
||||
* @uptr: Pointer to the user buffer for copy_from_user()
|
||||
* @len: The length of the user buffer in bytes
|
||||
*
|
||||
* A user space data is an uAPI that is defined in include/uapi/linux/iommufd.h
|
||||
* @type, @uptr and @len should be just copied from an iommufd core uAPI struct.
|
||||
*/
|
||||
struct iommu_user_data {
|
||||
unsigned int type;
|
||||
void __user *uptr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iommu_ops - iommu ops and capabilities
|
||||
* @capable: check capability
|
||||
@ -279,8 +294,12 @@ struct iommu_dirty_ops {
|
||||
* parameters as defined in include/uapi/linux/iommufd.h.
|
||||
* Unlike @domain_alloc, it is called only by IOMMUFD and
|
||||
* must fully initialize the new domain before return.
|
||||
* Upon success, a domain is returned. Upon failure,
|
||||
* ERR_PTR must be returned.
|
||||
* Upon success, if the @user_data is valid and the @parent
|
||||
* points to a kernel-managed domain, the new domain must be
|
||||
* IOMMU_DOMAIN_NESTED type; otherwise, the @parent must be
|
||||
* NULL while the @user_data can be optionally provided, the
|
||||
* new domain must support __IOMMU_DOMAIN_PAGING.
|
||||
* Upon failure, ERR_PTR must be returned.
|
||||
* @probe_device: Add device to iommu driver handling
|
||||
* @release_device: Remove device from iommu driver handling
|
||||
* @probe_finalize: Do final setup work after the device is added to an IOMMU
|
||||
@ -313,7 +332,9 @@ struct iommu_ops {
|
||||
|
||||
/* Domain allocation and freeing by the iommu driver */
|
||||
struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
|
||||
struct iommu_domain *(*domain_alloc_user)(struct device *dev, u32 flags);
|
||||
struct iommu_domain *(*domain_alloc_user)(
|
||||
struct device *dev, u32 flags, struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data);
|
||||
|
||||
struct iommu_device *(*probe_device)(struct device *dev);
|
||||
void (*release_device)(struct device *dev);
|
||||
|
Loading…
Reference in New Issue
Block a user