On Fri, Apr 25, 2025 at 10:58:04PM -0700, Nicolin Chen wrote:
> Add a new IOMMUFD_OBJ_VCMDQ with an iommufd_vcmdq structure, representing
> a command queue type of physical HW passed to a user space VM. This vCMDQ
> object, is a subset of vIOMMU resources of a physical IOMMU's, such as:
>  - NVIDIA's virtual command queue
>  - AMD vIOMMU's command buffer
> 
> Inroduce a struct iommufd_vcmdq and its allocator iommufd_vcmdq_alloc().
> Also add a pair of viommu ops for iommufd to forward user space ioctls to
> IOMMU drivers.
> 
> Signed-off-by: Nicolin Chen <nicol...@nvidia.com>

Reviewed-by: Pranjal Shrivastava <pr...@google.com>

> ---
>  include/linux/iommufd.h | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 
> diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
> index ef0d3c4765cf..e91381aaec5a 100644
> --- a/include/linux/iommufd.h
> +++ b/include/linux/iommufd.h
> @@ -37,6 +37,7 @@ enum iommufd_object_type {
>       IOMMUFD_OBJ_VIOMMU,
>       IOMMUFD_OBJ_VDEVICE,
>       IOMMUFD_OBJ_VEVENTQ,
> +     IOMMUFD_OBJ_VCMDQ,
>  #ifdef CONFIG_IOMMUFD_TEST
>       IOMMUFD_OBJ_SELFTEST,
>  #endif
> @@ -112,6 +113,14 @@ struct iommufd_vdevice {
>       u64 id; /* per-vIOMMU virtual ID */
>  };
>  
> +struct iommufd_vcmdq {
> +     struct iommufd_object obj;
> +     struct iommufd_ctx *ictx;
> +     struct iommufd_viommu *viommu;
> +     dma_addr_t addr;
> +     size_t length;
> +};
> +
>  /**
>   * struct iommufd_viommu_ops - vIOMMU specific operations
>   * @destroy: Clean up all driver-specific parts of an iommufd_viommu. The 
> memory
> @@ -135,6 +144,13 @@ struct iommufd_vdevice {
>   * @vdevice_destroy: Clean up all driver-specific parts of an 
> iommufd_vdevice.
>   *                   The memory of the vDEVICE will be free-ed by iommufd 
> core
>   *                   after calling this op
> + * @vcmdq_alloc: Allocate a @type of iommufd_vcmdq as a user space command 
> queue
> + *               for a @viommu. @index carries the logical vcmdq ID (for a 
> multi-
> + *               queue case); @addr carries the guest physical base address 
> of
> + *               the queue memory; @length carries the size of the queue 
> memory
> + * @vcmdq_destroy: Clean up all driver-specific parts of an iommufd_vcmdq. 
> The
> + *                 memory of the iommufd_vcmdq will be free-ed by iommufd 
> core
> + *                 after calling this op
>   */
>  struct iommufd_viommu_ops {
>       void (*destroy)(struct iommufd_viommu *viommu);
> @@ -147,6 +163,10 @@ struct iommufd_viommu_ops {
>                                                struct device *dev,
>                                                u64 virt_id);
>       void (*vdevice_destroy)(struct iommufd_vdevice *vdev);
> +     struct iommufd_vcmdq *(*vcmdq_alloc)(struct iommufd_viommu *viommu,
> +                                          unsigned int type, u32 index,
> +                                          dma_addr_t addr, size_t length);
> +     void (*vcmdq_destroy)(struct iommufd_vcmdq *vcmdq);
>  };
>  
>  #if IS_ENABLED(CONFIG_IOMMUFD)
> @@ -286,6 +306,21 @@ static inline int iommufd_viommu_report_event(struct 
> iommufd_viommu *viommu,
>               ret;                                                           \
>       })
>  
> +#define iommufd_vcmdq_alloc(viommu, drv_struct, member)                      
>   \
> +     ({                                                                     \
> +             drv_struct *ret;                                               \
> +                                                                            \
> +             static_assert(__same_type(struct iommufd_viommu, *viommu));    \
> +             static_assert(__same_type(struct iommufd_vcmdq,                \
> +                                       ((drv_struct *)NULL)->member));      \
> +             static_assert(offsetof(drv_struct, member.obj) == 0);          \
> +             ret = (drv_struct *)_iommufd_object_alloc(                     \
> +                     viommu->ictx, sizeof(drv_struct), IOMMUFD_OBJ_VCMDQ);  \
> +             if (!IS_ERR(ret))                                              \
> +                     ret->member.viommu = viommu;                           \
> +             ret;                                                           \
> +     })
> +
>  /* Helper for IOMMU driver to destroy structures created by allocators above 
> */
>  #define iommufd_struct_destroy(ictx, drv_struct, member)                     
>   \
>       ({                                                                     \
> -- 
> 2.43.0
> 

Reply via email to