On Fri, Jul 05, 2019 at 07:01:38PM +0800, Liu Yi L wrote: > This patch adds vfio implementation PCIPASIDOps.alloc_pasid/free_pasid(). > These two functions are used to propagate guest pasid allocation and > free requests to host via vfio container ioctl. > > Cc: Kevin Tian <kevin.tian@xxxxxxxxx> > Cc: Jacob Pan <jacob.jun.pan@xxxxxxxxxxxxxxx> > Cc: Peter Xu <peterx@xxxxxxxxxx> > Cc: Eric Auger <eric.auger@xxxxxxxxxx> > Cc: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> > Cc: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> > Signed-off-by: Liu Yi L <yi.l.liu@xxxxxxxxx> > Signed-off-by: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> > --- > hw/vfio/pci.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 61 insertions(+) > > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c > index ce3fe96..ab184ad 100644 > --- a/hw/vfio/pci.c > +++ b/hw/vfio/pci.c > @@ -2690,6 +2690,65 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev) > vdev->req_enabled = false; > } > > +static int vfio_pci_device_request_pasid_alloc(PCIBus *bus, > + int32_t devfn, > + uint32_t min_pasid, > + uint32_t max_pasid) > +{ > + PCIDevice *pdev = bus->devices[devfn]; > + VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); > + VFIOContainer *container = vdev->vbasedev.group->container; > + struct vfio_iommu_type1_pasid_request req; > + unsigned long argsz; > + int pasid; > + > + argsz = sizeof(req); > + req.argsz = argsz; > + req.flag = VFIO_IOMMU_PASID_ALLOC; > + req.min_pasid = min_pasid; > + req.max_pasid = max_pasid; > + > + rcu_read_lock(); Could I ask what's this RCU lock protecting? > + pasid = ioctl(container->fd, VFIO_IOMMU_PASID_REQUEST, &req); > + if (pasid < 0) { > + error_report("vfio_pci_device_request_pasid_alloc:" > + " request failed, contanier: %p", container); Can use __func__, also since we're going to dump the error after all, we can also include the errno (pasid) here which seems to be more helpful than the container pointer at least to me. :) > + } > + rcu_read_unlock(); > + return pasid; > +} > + > +static int vfio_pci_device_request_pasid_free(PCIBus *bus, > + int32_t devfn, > + uint32_t pasid) > +{ > + PCIDevice *pdev = bus->devices[devfn]; > + VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); > + VFIOContainer *container = vdev->vbasedev.group->container; > + struct vfio_iommu_type1_pasid_request req; > + unsigned long argsz; > + int ret = 0; > + > + argsz = sizeof(req); > + req.argsz = argsz; > + req.flag = VFIO_IOMMU_PASID_FREE; > + req.pasid = pasid; > + > + rcu_read_lock(); > + ret = ioctl(container->fd, VFIO_IOMMU_PASID_REQUEST, &req); > + if (ret != 0) { > + error_report("vfio_pci_device_request_pasid_free:" > + " request failed, contanier: %p", container); > + } > + rcu_read_unlock(); > + return ret; > +} > + > +static PCIPASIDOps vfio_pci_pasid_ops = { > + .alloc_pasid = vfio_pci_device_request_pasid_alloc, > + .free_pasid = vfio_pci_device_request_pasid_free, > +}; > + > static void vfio_realize(PCIDevice *pdev, Error **errp) > { > VFIOPCIDevice *vdev = PCI_VFIO(pdev); > @@ -2991,6 +3050,8 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) > vfio_register_req_notifier(vdev); > vfio_setup_resetfn_quirk(vdev); > > + pci_setup_pasid_ops(pdev, &vfio_pci_pasid_ops); > + > return; > > out_teardown: > -- > 2.7.4 > Regards, -- Peter Xu