Message ID | 556347d2e69e8b236ec946a93132181385344d4f.1728491532.git.nicolinc@nvidia.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | cover-letter: iommufd: Add vIOMMU infrastructure (Part-2: vDEVICE) | expand |
> +struct iommufd_vdevice * > +__iommufd_vdevice_alloc(struct iommufd_ctx *ictx, size_t size) > +{ > + struct iommufd_object *obj; > + > + if (WARN_ON(size < sizeof(struct iommufd_vdevice))) > + return ERR_PTR(-EINVAL); > + obj = iommufd_object_alloc_elm(ictx, size, IOMMUFD_OBJ_VDEVICE); > + if (IS_ERR(obj)) > + return ERR_CAST(obj); > + return container_of(obj, struct iommufd_vdevice, obj); > +} Like for the viommu this can all just be folded into the #define Jason
On Thu, Oct 17, 2024 at 03:45:56PM -0300, Jason Gunthorpe wrote: > > +struct iommufd_vdevice * > > +__iommufd_vdevice_alloc(struct iommufd_ctx *ictx, size_t size) > > +{ > > + struct iommufd_object *obj; > > + > > + if (WARN_ON(size < sizeof(struct iommufd_vdevice))) > > + return ERR_PTR(-EINVAL); > > + obj = iommufd_object_alloc_elm(ictx, size, IOMMUFD_OBJ_VDEVICE); > > + if (IS_ERR(obj)) > > + return ERR_CAST(obj); > > + return container_of(obj, struct iommufd_vdevice, obj); > > +} > > Like for the viommu this can all just be folded into the #define It seems that we have to keep two small functions as followings, unless we want to expose the enum iommufd_object_type. --------------------------------------------------------------- diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c index 4495f1aaccca..fdd203487bac 100644 --- a/drivers/iommu/iommufd/driver.c +++ b/drivers/iommu/iommufd/driver.c @@ -38,10 +38,19 @@ _iommufd_object_alloc_member(struct iommufd_ctx *ictx, size_t size, EXPORT_SYMBOL_NS_GPL(_iommufd_object_alloc_member, IOMMUFD); struct iommufd_viommu *_iommufd_viommu_alloc(struct iommufd_ctx *ictx, size_t size) { return container_of(_iommufd_object_alloc_member(ictx, size, IOMMUFD_OBJ_VIOMMU), struct iommufd_viommu, obj); } EXPORT_SYMBOL_NS_GPL(_iommufd_viommu_alloc, IOMMUFD); + +struct iommufd_vdevice *_iommufd_vdevice_alloc(struct iommufd_ctx *ictx, + size_t size) +{ + return container_of(_iommufd_object_alloc_member(ictx, size, + IOMMUFD_OBJ_VDEVICE), + struct iommufd_vdevice, obj); +} +EXPORT_SYMBOL_NS_GPL(_iommufd_vdevice_alloc, IOMMUFD); --------------------------------------------------------------- Thanks Nicolin
On Sat, Oct 19, 2024 at 06:35:45PM -0700, Nicolin Chen wrote: > On Thu, Oct 17, 2024 at 03:45:56PM -0300, Jason Gunthorpe wrote: > > > +struct iommufd_vdevice * > > > +__iommufd_vdevice_alloc(struct iommufd_ctx *ictx, size_t size) > > > +{ > > > + struct iommufd_object *obj; > > > + > > > + if (WARN_ON(size < sizeof(struct iommufd_vdevice))) > > > + return ERR_PTR(-EINVAL); > > > + obj = iommufd_object_alloc_elm(ictx, size, IOMMUFD_OBJ_VDEVICE); > > > + if (IS_ERR(obj)) > > > + return ERR_CAST(obj); > > > + return container_of(obj, struct iommufd_vdevice, obj); > > > +} > > > > Like for the viommu this can all just be folded into the #define > > It seems that we have to keep two small functions as followings, > unless we want to expose the enum iommufd_object_type. I'd probably expose the enum along with the struct.. Jason
On Mon, Oct 21, 2024 at 09:21:48AM -0300, Jason Gunthorpe wrote: > On Sat, Oct 19, 2024 at 06:35:45PM -0700, Nicolin Chen wrote: > > On Thu, Oct 17, 2024 at 03:45:56PM -0300, Jason Gunthorpe wrote: > > > > +struct iommufd_vdevice * > > > > +__iommufd_vdevice_alloc(struct iommufd_ctx *ictx, size_t size) > > > > +{ > > > > + struct iommufd_object *obj; > > > > + > > > > + if (WARN_ON(size < sizeof(struct iommufd_vdevice))) > > > > + return ERR_PTR(-EINVAL); > > > > + obj = iommufd_object_alloc_elm(ictx, size, IOMMUFD_OBJ_VDEVICE); > > > > + if (IS_ERR(obj)) > > > > + return ERR_CAST(obj); > > > > + return container_of(obj, struct iommufd_vdevice, obj); > > > > +} > > > > > > Like for the viommu this can all just be folded into the #define > > > > It seems that we have to keep two small functions as followings, > > unless we want to expose the enum iommufd_object_type. > > I'd probably expose the enum along with the struct.. OK. Let's do that. Nicolin
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index c80d880f8b6a..0c56a467e440 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -132,6 +132,7 @@ enum iommufd_object_type { IOMMUFD_OBJ_ACCESS, IOMMUFD_OBJ_FAULT, IOMMUFD_OBJ_VIOMMU, + IOMMUFD_OBJ_VDEVICE, #ifdef CONFIG_IOMMUFD_TEST IOMMUFD_OBJ_SELFTEST, #endif diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h index 069a38999cdd..510fc961a9ad 100644 --- a/include/linux/iommufd.h +++ b/include/linux/iommufd.h @@ -75,13 +75,30 @@ struct iommufd_viommu { unsigned int type; }; +struct iommufd_vdevice { + struct iommufd_object obj; + struct iommufd_ctx *ictx; + struct iommufd_device *idev; + struct iommufd_viommu *viommu; + u64 id; /* per-vIOMMU virtual ID */ +}; + /** * struct iommufd_viommu_ops - vIOMMU specific operations * @free: Free all driver-specific parts of an iommufd_viommu. The memory of the * vIOMMU will be free-ed by iommufd core after calling this free op. + * @vdevice_alloc: Allocate a driver-managed iommufd_vdevice to init some driver + * specific structure or HW procedure. Note that the core-level + * structure is filled by the iommufd core after calling this op. + * @vdevice_free: Free a driver-managed iommufd_vdevice to de-init its structure + * or HW procedure. The memory of the vdevice will be free-ed by + * iommufd core. */ struct iommufd_viommu_ops { void (*free)(struct iommufd_viommu *viommu); + struct iommufd_vdevice *(*vdevice_alloc)(struct iommufd_viommu *viommu, + struct device *dev, u64 id); + void (*vdevice_free)(struct iommufd_vdevice *vdev); }; #if IS_ENABLED(CONFIG_IOMMUFD) @@ -103,6 +120,8 @@ int iommufd_vfio_compat_set_no_iommu(struct iommufd_ctx *ictx); struct iommufd_viommu * __iommufd_viommu_alloc(struct iommufd_ctx *ictx, size_t size, const struct iommufd_viommu_ops *ops); +struct iommufd_vdevice * +__iommufd_vdevice_alloc(struct iommufd_ctx *ictx, size_t size); #else /* !CONFIG_IOMMUFD */ static inline struct iommufd_ctx *iommufd_ctx_from_file(struct file *file) { @@ -150,6 +169,12 @@ __iommufd_viommu_alloc(struct iommufd_ctx *ictx, size_t size, { return ERR_PTR(-EOPNOTSUPP); } + +static inline struct iommufd_vdevice * +__iommufd_vdevice_alloc(struct iommufd_ctx *ictx, size_t size) +{ + return ERR_PTR(-EOPNOTSUPP); +} #endif /* CONFIG_IOMMUFD */ /* @@ -163,4 +188,10 @@ __iommufd_viommu_alloc(struct iommufd_ctx *ictx, size_t size, struct drv_struct, member)), \ ops), \ struct drv_struct, member) +#define iommufd_vdevice_alloc(ictx, drv_struct, member) \ + container_of(__iommufd_vdevice_alloc(ictx, \ + sizeof(struct drv_struct) + \ + BUILD_BUG_ON_ZERO(offsetof( \ + struct drv_struct, member))), \ + struct drv_struct, member) #endif diff --git a/drivers/iommu/iommufd/viommu_api.c b/drivers/iommu/iommufd/viommu_api.c index c1731f080d6b..8419df3b658c 100644 --- a/drivers/iommu/iommufd/viommu_api.c +++ b/drivers/iommu/iommufd/viommu_api.c @@ -55,3 +55,17 @@ __iommufd_viommu_alloc(struct iommufd_ctx *ictx, size_t size, return viommu; } EXPORT_SYMBOL_NS_GPL(__iommufd_viommu_alloc, IOMMUFD); + +struct iommufd_vdevice * +__iommufd_vdevice_alloc(struct iommufd_ctx *ictx, size_t size) +{ + struct iommufd_object *obj; + + if (WARN_ON(size < sizeof(struct iommufd_vdevice))) + return ERR_PTR(-EINVAL); + obj = iommufd_object_alloc_elm(ictx, size, IOMMUFD_OBJ_VDEVICE); + if (IS_ERR(obj)) + return ERR_CAST(obj); + return container_of(obj, struct iommufd_vdevice, obj); +} +EXPORT_SYMBOL_NS_GPL(__iommufd_vdevice_alloc, IOMMUFD);
Introduce a new IOMMUFD_OBJ_VDEVICE to represent a physical device, i.e. iommufd_device (idev) object, against an iommufd_viommu (vIOMMU) object in the VM. This vDEVICE object (and its structure) holds all the information and attributes in a VM, regarding the device related to the vIOMMU. As an initial patch, add a per-vIOMMU virtual ID. This can be: - Virtual StreamID on a nested ARM SMMUv3, an index to a Stream Table - Virtual DeviceID on a nested AMD IOMMU, an index to a Device Table - Virtual ID on a nested Intel VT-D IOMMU, an index to a Context Table Potentially, this vDEVICE structure can hold some vData for Confidential Compute Architecture (CCA). Add a pair of vdevice_alloc and vdevice_free in struct iommufd_viommu_ops to allow driver-level vDEVICE structure allocations. Similar to iommufd_vdevice_alloc, add an iommufd_vdevice_alloc helper so IOMMU drivers can allocate core-embedded style structures. Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> --- drivers/iommu/iommufd/iommufd_private.h | 1 + include/linux/iommufd.h | 31 +++++++++++++++++++++++++ drivers/iommu/iommufd/viommu_api.c | 14 +++++++++++ 3 files changed, 46 insertions(+)