[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <PH0PR11MB565826922F160F541249FB0AC3B99@PH0PR11MB5658.namprd11.prod.outlook.com>
Date: Fri, 15 Oct 2021 09:21:29 +0000
From: "Liu, Yi L" <yi.l.liu@...el.com>
To: Jason Gunthorpe <jgg@...dia.com>
CC: "alex.williamson@...hat.com" <alex.williamson@...hat.com>,
"hch@....de" <hch@....de>,
"jasowang@...hat.com" <jasowang@...hat.com>,
"joro@...tes.org" <joro@...tes.org>,
"jean-philippe@...aro.org" <jean-philippe@...aro.org>,
"Tian, Kevin" <kevin.tian@...el.com>,
"parav@...lanox.com" <parav@...lanox.com>,
"lkml@...ux.net" <lkml@...ux.net>,
"pbonzini@...hat.com" <pbonzini@...hat.com>,
"lushenming@...wei.com" <lushenming@...wei.com>,
"eric.auger@...hat.com" <eric.auger@...hat.com>,
"corbet@....net" <corbet@....net>,
"Raj, Ashok" <ashok.raj@...el.com>,
"yi.l.liu@...ux.intel.com" <yi.l.liu@...ux.intel.com>,
"Tian, Jun J" <jun.j.tian@...el.com>, "Wu, Hao" <hao.wu@...el.com>,
"Jiang, Dave" <dave.jiang@...el.com>,
"jacob.jun.pan@...ux.intel.com" <jacob.jun.pan@...ux.intel.com>,
"kwankhede@...dia.com" <kwankhede@...dia.com>,
"robin.murphy@....com" <robin.murphy@....com>,
"kvm@...r.kernel.org" <kvm@...r.kernel.org>,
"iommu@...ts.linux-foundation.org" <iommu@...ts.linux-foundation.org>,
"dwmw2@...radead.org" <dwmw2@...radead.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"baolu.lu@...ux.intel.com" <baolu.lu@...ux.intel.com>,
"david@...son.dropbear.id.au" <david@...son.dropbear.id.au>,
"nicolinc@...dia.com" <nicolinc@...dia.com>
Subject: RE: [RFC 07/20] iommu/iommufd: Add iommufd_[un]bind_device()
> From: Jason Gunthorpe <jgg@...dia.com>
> Sent: Wednesday, September 22, 2021 1:15 AM
>
> On Sun, Sep 19, 2021 at 02:38:35PM +0800, Liu Yi L wrote:
>
> > +/*
> > + * A iommufd_device object represents the binding relationship
> > + * between iommufd and device. It is created per a successful
> > + * binding request from device driver. The bound device must be
> > + * a physical device so far. Subdevice will be supported later
> > + * (with additional PASID information). An user-assigned cookie
> > + * is also recorded to mark the device in the /dev/iommu uAPI.
> > + */
> > +struct iommufd_device {
> > + unsigned int id;
> > + struct iommufd_ctx *ictx;
> > + struct device *dev; /* always be the physical device */
> > + u64 dev_cookie;
> > };
> >
> > static int iommufd_fops_open(struct inode *inode, struct file *filep)
> > @@ -32,15 +52,58 @@ static int iommufd_fops_open(struct inode *inode,
> struct file *filep)
> > return -ENOMEM;
> >
> > refcount_set(&ictx->refs, 1);
> > + mutex_init(&ictx->lock);
> > + xa_init_flags(&ictx->device_xa, XA_FLAGS_ALLOC);
> > filep->private_data = ictx;
> >
> > return ret;
> > }
> >
> > +static void iommufd_ctx_get(struct iommufd_ctx *ictx)
> > +{
> > + refcount_inc(&ictx->refs);
> > +}
>
> See my earlier remarks about how to structure the lifetime logic, this
> ref isn't necessary.
>
> > +static const struct file_operations iommufd_fops;
> > +
> > +/**
> > + * iommufd_ctx_fdget - Acquires a reference to the internal iommufd
> context.
> > + * @fd: [in] iommufd file descriptor.
> > + *
> > + * Returns a pointer to the iommufd context, otherwise NULL;
> > + *
> > + */
> > +static struct iommufd_ctx *iommufd_ctx_fdget(int fd)
> > +{
> > + struct fd f = fdget(fd);
> > + struct file *file = f.file;
> > + struct iommufd_ctx *ictx;
> > +
> > + if (!file)
> > + return NULL;
> > +
> > + if (file->f_op != &iommufd_fops)
> > + return NULL;
>
> Leaks the fdget
>
> > +
> > + ictx = file->private_data;
> > + if (ictx)
> > + iommufd_ctx_get(ictx);
>
> Use success oriented flow
>
> > + fdput(f);
> > + return ictx;
> > +}
>
> > + */
> > +struct iommufd_device *iommufd_bind_device(int fd, struct device *dev,
> > + u64 dev_cookie)
> > +{
> > + struct iommufd_ctx *ictx;
> > + struct iommufd_device *idev;
> > + unsigned long index;
> > + unsigned int id;
> > + int ret;
> > +
> > + ictx = iommufd_ctx_fdget(fd);
> > + if (!ictx)
> > + return ERR_PTR(-EINVAL);
> > +
> > + mutex_lock(&ictx->lock);
> > +
> > + /* check duplicate registration */
> > + xa_for_each(&ictx->device_xa, index, idev) {
> > + if (idev->dev == dev || idev->dev_cookie == dev_cookie) {
> > + idev = ERR_PTR(-EBUSY);
> > + goto out_unlock;
> > + }
>
> I can't think of a reason why this expensive check is needed.
>
> > + }
> > +
> > + idev = kzalloc(sizeof(*idev), GFP_KERNEL);
> > + if (!idev) {
> > + ret = -ENOMEM;
> > + goto out_unlock;
> > + }
> > +
> > + /* Establish the security context */
> > + ret = iommu_device_init_user_dma(dev, (unsigned long)ictx);
> > + if (ret)
> > + goto out_free;
> > +
> > + ret = xa_alloc(&ictx->device_xa, &id, idev,
> > + XA_LIMIT(IOMMUFD_DEVID_MIN,
> IOMMUFD_DEVID_MAX),
> > + GFP_KERNEL);
>
> idev should be fully initialized before being placed in the xarray, so
> this should be the last thing done.
all good suggestions above. thanks for catching them.
> Why not just use the standard xa_limit_32b instead of special single
> use constants?
yeah. should use xa_limit_32b.
Regards,
Yi Liu
> Jason
Powered by blists - more mailing lists