Hi Kevin, > From: Tian, Kevin > Sent: Friday, October 25, 2019 6:06 PM > To: Liu, Yi L <yi.l.liu@xxxxxxxxx>; alex.williamson@xxxxxxxxxx; > Subject: RE: [RFC v2 2/3] vfio/type1: VFIO_IOMMU_PASID_REQUEST(alloc/free) > > > From: Liu Yi L > > Sent: Thursday, October 24, 2019 8:26 PM > > > > This patch adds VFIO_IOMMU_PASID_REQUEST ioctl which aims to passdown > > PASID allocation/free request from the virtual iommu. This is required > > to get PASID managed in system-wide. > > > > Cc: Kevin Tian <kevin.tian@xxxxxxxxx> > > Signed-off-by: Liu Yi L <yi.l.liu@xxxxxxxxx> > > Signed-off-by: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> > > Signed-off-by: Jacob Pan <jacob.jun.pan@xxxxxxxxxxxxxxx> > > --- > > drivers/vfio/vfio_iommu_type1.c | 114 > > ++++++++++++++++++++++++++++++++++++++++ > > include/uapi/linux/vfio.h | 25 +++++++++ > > 2 files changed, 139 insertions(+) > > > > diff --git a/drivers/vfio/vfio_iommu_type1.c > > b/drivers/vfio/vfio_iommu_type1.c index cd8d3a5..3d73a7d 100644 > > --- a/drivers/vfio/vfio_iommu_type1.c > > +++ b/drivers/vfio/vfio_iommu_type1.c > > @@ -2248,6 +2248,83 @@ static int vfio_cache_inv_fn(struct device > > *dev, void *data) > > return iommu_cache_invalidate(dc->domain, dev, &ustruct->info); } > > > > +static int vfio_iommu_type1_pasid_alloc(struct vfio_iommu *iommu, > > + int min_pasid, > > + int max_pasid) > > +{ > > + int ret; > > + ioasid_t pasid; > > + struct mm_struct *mm = NULL; > > + > > + mutex_lock(&iommu->lock); > > + if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) { > > + ret = -EINVAL; > > + goto out_unlock; > > + } > > + mm = get_task_mm(current); > > + /* Track ioasid allocation owner by mm */ > below is purely allocation. Where does 'track' come to play? ioasid_set is kind of owner track. As allocation is separate with bind, here set the "owner" could be used to do sanity check when a pasid bind comes. > > + pasid = ioasid_alloc((struct ioasid_set *)mm, min_pasid, > > + max_pasid, NULL); > > + if (pasid == INVALID_IOASID) { > > + ret = -ENOSPC; > > + goto out_unlock; > > + } > > + ret = pasid; > > +out_unlock: > > + mutex_unlock(&iommu->lock); > > + if (mm) > > + mmput(mm); > > + return ret; > > +} > > + > > +static int vfio_iommu_type1_pasid_free(struct vfio_iommu *iommu, > > + unsigned int pasid) > > +{ > > + struct mm_struct *mm = NULL; > > + void *pdata; > > + int ret = 0; > > + > > + mutex_lock(&iommu->lock); > > + if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) { > > + ret = -EINVAL; > > + goto out_unlock; > > + } > > + > > + /** > > + * REVISIT: > > + * There are two cases free could fail: > > + * 1. free pasid by non-owner, we use ioasid_set to track mm, if > > + * the set does not match, caller is not permitted to free. > > + * 2. free before unbind all devices, we can check if ioasid private > > + * data, if data != NULL, then fail to free. > > + */ > > Does REVISIT mean that above comment is the right way but the code doesn't follow > yet, or the comment itself should be revisited? Sorry, it's a mistake... should be removed. It's added in the development phase for remind. Will remove it. > > should we have some notification mechanism, so the guy who holds the reference to > the pasid can be notified to release its usage? Do you mean the ioasid itself to provide such a notification mechanism? Currently, we prevent pasid free before all user (iommu driver, guest) released their usage. This is achieved by checking the private data, in which there is a user_cnt of a pasid. e.g. struct intel_svm. A fresh guest pasid bind will allocate the private data. A second guest pasid bind will increase the user_cnt. guest pasid unbind decreases the user_cnt. The private data will be freed by the last guest pasid unbind. Do you think it is sufficient? or we may want to have a notification mechanism to allow such pasid free and keep the user updated? Thanks, Yi Liu