mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
iommufd: Introduce IOMMUFD_OBJ_VIOMMU and its related struct
Add a new IOMMUFD_OBJ_VIOMMU with an iommufd_viommu structure to represent
a slice of physical IOMMU device passed to or shared with a user space VM.
This slice, now a vIOMMU object, is a group of virtualization resources of
a physical IOMMU's, such as:
- Security namespace for guest owned ID, e.g. guest-controlled cache tags
- Non-device-affiliated event reporting, e.g. invalidation queue errors
- Access to a sharable nesting parent pagetable across physical IOMMUs
- Virtualization of various platforms IDs, e.g. RIDs and others
- Delivery of paravirtualized invalidation
- Direct assigned invalidation queues
- Direct assigned interrupts
Add a new viommu_alloc op in iommu_ops, for drivers to allocate their own
vIOMMU structures. And this allocation also needs a free(), so add struct
iommufd_viommu_ops.
To simplify a vIOMMU allocation, provide a iommufd_viommu_alloc() helper.
It's suggested that a driver should embed a core-level viommu structure in
its driver-level viommu struct and call the iommufd_viommu_alloc() helper,
meanwhile the driver can also implement a viommu ops:
struct my_driver_viommu {
struct iommufd_viommu core;
/* driver-owned properties/features */
....
};
static const struct iommufd_viommu_ops my_driver_viommu_ops = {
.free = my_driver_viommu_free,
/* future ops for virtualization features */
....
};
static struct iommufd_viommu my_driver_viommu_alloc(...)
{
struct my_driver_viommu *my_viommu =
iommufd_viommu_alloc(ictx, my_driver_viommu, core,
my_driver_viommu_ops);
/* Init my_viommu and related HW feature */
....
return &my_viommu->core;
}
static struct iommu_domain_ops my_driver_domain_ops = {
....
.viommu_alloc = my_driver_viommu_alloc,
};
Link: https://patch.msgid.link/r/64685e2b79dea0f1dc56f6ede04809b72d578935.1730836219.git.nicolinc@nvidia.com
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
7d4f46c237
commit
6b22d562fc
|
|
@ -42,6 +42,8 @@ struct notifier_block;
|
|||
struct iommu_sva;
|
||||
struct iommu_dma_cookie;
|
||||
struct iommu_fault_param;
|
||||
struct iommufd_ctx;
|
||||
struct iommufd_viommu;
|
||||
|
||||
#define IOMMU_FAULT_PERM_READ (1 << 0) /* read */
|
||||
#define IOMMU_FAULT_PERM_WRITE (1 << 1) /* write */
|
||||
|
|
@ -542,6 +544,14 @@ static inline int __iommu_copy_struct_from_user_array(
|
|||
* @remove_dev_pasid: Remove any translation configurations of a specific
|
||||
* pasid, so that any DMA transactions with this pasid
|
||||
* will be blocked by the hardware.
|
||||
* @viommu_alloc: Allocate an iommufd_viommu on a physical IOMMU instance behind
|
||||
* the @dev, as the set of virtualization resources shared/passed
|
||||
* to user space IOMMU instance. And associate it with a nesting
|
||||
* @parent_domain. The @viommu_type must be defined in the header
|
||||
* include/uapi/linux/iommufd.h
|
||||
* It is required to call iommufd_viommu_alloc() helper for
|
||||
* a bundled allocation of the core and the driver structures,
|
||||
* using the given @ictx pointer.
|
||||
* @pgsize_bitmap: bitmap of all possible supported page sizes
|
||||
* @owner: Driver module providing these ops
|
||||
* @identity_domain: An always available, always attachable identity
|
||||
|
|
@ -591,6 +601,10 @@ struct iommu_ops {
|
|||
void (*remove_dev_pasid)(struct device *dev, ioasid_t pasid,
|
||||
struct iommu_domain *domain);
|
||||
|
||||
struct iommufd_viommu *(*viommu_alloc)(
|
||||
struct device *dev, struct iommu_domain *parent_domain,
|
||||
struct iommufd_ctx *ictx, unsigned int viommu_type);
|
||||
|
||||
const struct iommu_domain_ops *default_domain_ops;
|
||||
unsigned long pgsize_bitmap;
|
||||
struct module *owner;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ struct iommu_group;
|
|||
struct iommufd_access;
|
||||
struct iommufd_ctx;
|
||||
struct iommufd_device;
|
||||
struct iommufd_viommu_ops;
|
||||
struct page;
|
||||
|
||||
enum iommufd_object_type {
|
||||
|
|
@ -28,6 +29,7 @@ enum iommufd_object_type {
|
|||
IOMMUFD_OBJ_IOAS,
|
||||
IOMMUFD_OBJ_ACCESS,
|
||||
IOMMUFD_OBJ_FAULT,
|
||||
IOMMUFD_OBJ_VIOMMU,
|
||||
#ifdef CONFIG_IOMMUFD_TEST
|
||||
IOMMUFD_OBJ_SELFTEST,
|
||||
#endif
|
||||
|
|
@ -78,6 +80,26 @@ void iommufd_access_detach(struct iommufd_access *access);
|
|||
|
||||
void iommufd_ctx_get(struct iommufd_ctx *ictx);
|
||||
|
||||
struct iommufd_viommu {
|
||||
struct iommufd_object obj;
|
||||
struct iommufd_ctx *ictx;
|
||||
struct iommu_device *iommu_dev;
|
||||
struct iommufd_hwpt_paging *hwpt;
|
||||
|
||||
const struct iommufd_viommu_ops *ops;
|
||||
|
||||
unsigned int type;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iommufd_viommu_ops - vIOMMU specific operations
|
||||
* @destroy: Clean up all driver-specific parts of an iommufd_viommu. The memory
|
||||
* of the vIOMMU will be free-ed by iommufd core after calling this op
|
||||
*/
|
||||
struct iommufd_viommu_ops {
|
||||
void (*destroy)(struct iommufd_viommu *viommu);
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_IOMMUFD)
|
||||
struct iommufd_ctx *iommufd_ctx_from_file(struct file *file);
|
||||
struct iommufd_ctx *iommufd_ctx_from_fd(int fd);
|
||||
|
|
@ -148,4 +170,22 @@ _iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size,
|
|||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
#endif /* CONFIG_IOMMUFD_DRIVER_CORE */
|
||||
|
||||
/*
|
||||
* Helpers for IOMMU driver to allocate driver structures that will be freed by
|
||||
* the iommufd core. The free op will be called prior to freeing the memory.
|
||||
*/
|
||||
#define iommufd_viommu_alloc(ictx, drv_struct, member, viommu_ops) \
|
||||
({ \
|
||||
drv_struct *ret; \
|
||||
\
|
||||
static_assert(__same_type(struct iommufd_viommu, \
|
||||
((drv_struct *)NULL)->member)); \
|
||||
static_assert(offsetof(drv_struct, member.obj) == 0); \
|
||||
ret = (drv_struct *)_iommufd_object_alloc( \
|
||||
ictx, sizeof(drv_struct), IOMMUFD_OBJ_VIOMMU); \
|
||||
if (!IS_ERR(ret)) \
|
||||
ret->member.ops = viommu_ops; \
|
||||
ret; \
|
||||
})
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user