Skip to content

Commit 2bdabb8

Browse files
yiliu1765jgunthorpe
authored andcommitted
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>
1 parent b5021cb commit 2bdabb8

File tree

5 files changed

+44
-9
lines changed

5 files changed

+44
-9
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,12 +2219,15 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned int type)
22192219
return domain;
22202220
}
22212221

2222-
static struct iommu_domain *amd_iommu_domain_alloc_user(struct device *dev,
2223-
u32 flags)
2222+
static struct iommu_domain *
2223+
amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
2224+
struct iommu_domain *parent,
2225+
const struct iommu_user_data *user_data)
2226+
22242227
{
22252228
unsigned int type = IOMMU_DOMAIN_UNMANAGED;
22262229

2227-
if (flags & ~IOMMU_HWPT_ALLOC_DIRTY_TRACKING)
2230+
if ((flags & ~IOMMU_HWPT_ALLOC_DIRTY_TRACKING) || parent || user_data)
22282231
return ERR_PTR(-EOPNOTSUPP);
22292232

22302233
return do_iommu_domain_alloc(type, dev, flags);

drivers/iommu/intel/iommu.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4076,7 +4076,9 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
40764076
}
40774077

40784078
static struct iommu_domain *
4079-
intel_iommu_domain_alloc_user(struct device *dev, u32 flags)
4079+
intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
4080+
struct iommu_domain *parent,
4081+
const struct iommu_user_data *user_data)
40804082
{
40814083
struct iommu_domain *domain;
40824084
struct intel_iommu *iommu;
@@ -4086,6 +4088,9 @@ intel_iommu_domain_alloc_user(struct device *dev, u32 flags)
40864088
(~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
40874089
return ERR_PTR(-EOPNOTSUPP);
40884090

4091+
if (parent || user_data)
4092+
return ERR_PTR(-EOPNOTSUPP);
4093+
40894094
iommu = device_to_iommu(dev, NULL, NULL);
40904095
if (!iommu)
40914096
return ERR_PTR(-ENODEV);

drivers/iommu/iommufd/hw_pagetable.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
108108
hwpt_paging->ioas = ioas;
109109

110110
if (ops->domain_alloc_user) {
111-
hwpt->domain = ops->domain_alloc_user(idev->dev, flags);
111+
hwpt->domain =
112+
ops->domain_alloc_user(idev->dev, flags, NULL, NULL);
112113
if (IS_ERR(hwpt->domain)) {
113114
rc = PTR_ERR(hwpt->domain);
114115
hwpt->domain = NULL;

drivers/iommu/iommufd/selftest.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
241241
}
242242

243243
static struct iommu_domain *
244-
mock_domain_alloc_user(struct device *dev, u32 flags)
244+
mock_domain_alloc_user(struct device *dev, u32 flags,
245+
struct iommu_domain *parent,
246+
const struct iommu_user_data *user_data)
245247
{
246248
struct mock_dev *mdev = container_of(dev, struct mock_dev, dev);
247249
struct iommu_domain *domain;
@@ -250,6 +252,9 @@ mock_domain_alloc_user(struct device *dev, u32 flags)
250252
(~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
251253
return ERR_PTR(-EOPNOTSUPP);
252254

255+
if (parent || user_data)
256+
return ERR_PTR(-EOPNOTSUPP);
257+
253258
if ((flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING) &&
254259
(mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
255260
return ERR_PTR(-EOPNOTSUPP);

include/linux/iommu.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,21 @@ struct iommu_dirty_ops {
265265
struct iommu_dirty_bitmap *dirty);
266266
};
267267

268+
/**
269+
* struct iommu_user_data - iommu driver specific user space data info
270+
* @type: The data type of the user buffer
271+
* @uptr: Pointer to the user buffer for copy_from_user()
272+
* @len: The length of the user buffer in bytes
273+
*
274+
* A user space data is an uAPI that is defined in include/uapi/linux/iommufd.h
275+
* @type, @uptr and @len should be just copied from an iommufd core uAPI struct.
276+
*/
277+
struct iommu_user_data {
278+
unsigned int type;
279+
void __user *uptr;
280+
size_t len;
281+
};
282+
268283
/**
269284
* struct iommu_ops - iommu ops and capabilities
270285
* @capable: check capability
@@ -279,8 +294,12 @@ struct iommu_dirty_ops {
279294
* parameters as defined in include/uapi/linux/iommufd.h.
280295
* Unlike @domain_alloc, it is called only by IOMMUFD and
281296
* must fully initialize the new domain before return.
282-
* Upon success, a domain is returned. Upon failure,
283-
* ERR_PTR must be returned.
297+
* Upon success, if the @user_data is valid and the @parent
298+
* points to a kernel-managed domain, the new domain must be
299+
* IOMMU_DOMAIN_NESTED type; otherwise, the @parent must be
300+
* NULL while the @user_data can be optionally provided, the
301+
* new domain must support __IOMMU_DOMAIN_PAGING.
302+
* Upon failure, ERR_PTR must be returned.
284303
* @probe_device: Add device to iommu driver handling
285304
* @release_device: Remove device from iommu driver handling
286305
* @probe_finalize: Do final setup work after the device is added to an IOMMU
@@ -313,7 +332,9 @@ struct iommu_ops {
313332

314333
/* Domain allocation and freeing by the iommu driver */
315334
struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
316-
struct iommu_domain *(*domain_alloc_user)(struct device *dev, u32 flags);
335+
struct iommu_domain *(*domain_alloc_user)(
336+
struct device *dev, u32 flags, struct iommu_domain *parent,
337+
const struct iommu_user_data *user_data);
317338

318339
struct iommu_device *(*probe_device)(struct device *dev);
319340
void (*release_device)(struct device *dev);

0 commit comments

Comments
 (0)