On Thu, 10 Oct 2024 at 00:40, Nicolin Chen <nicolinc@xxxxxxxxxx> wrote: > > 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 > - 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 > - Non-affiliated event reporting > > 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, > }; > > To make the Kernel config work between a driver and the iommufd core, put > the for-driver allocation helpers into a new viommu_api file building with > CONFIG_IOMMUFD_DRIVER. > > Signed-off-by: Nicolin Chen <nicolinc@xxxxxxxxxx> > diff --git a/drivers/iommu/iommufd/viommu_api.c b/drivers/iommu/iommufd/viommu_api.c > new file mode 100644 > index 000000000000..c1731f080d6b > --- /dev/null > +++ b/drivers/iommu/iommufd/viommu_api.c > @@ -0,0 +1,57 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES > + */ > + > +#include "iommufd_private.h" > + > +struct iommufd_object *iommufd_object_alloc_elm(struct iommufd_ctx *ictx, > + size_t size, > + enum iommufd_object_type type) > +{ > + struct iommufd_object *obj; > + int rc; > + > + obj = kzalloc(size, GFP_KERNEL_ACCOUNT); > + if (!obj) > + return ERR_PTR(-ENOMEM); > + obj->type = type; > + /* Starts out bias'd by 1 until it is removed from the xarray */ > + refcount_set(&obj->shortterm_users, 1); > + refcount_set(&obj->users, 1); here set refcont 1 iommufd_device_bind -> iommufd_object_alloc(ictx, idev, IOMMUFD_OBJ_DEVICE): refcont -> 1 refcount_inc(&idev->obj.users); refcount -> 2 will cause iommufd_device_unbind fail. May remove refcount_inc(&idev->obj.users) in iommufd_device_bind Thanks