Message ID | 1580300216-86172-13-git-send-email-yi.l.liu@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | intel_iommu: expose Shared Virtual Addressing to VMs | expand |
On Wed, Jan 29, 2020 at 04:16:43AM -0800, Liu, Yi L wrote: > From: Liu Yi L <yi.l.liu@intel.com> > > This patch adds VFIO pasid alloc/free support to allow host intercept > in PASID allocation for VM by adding VFIO implementation of > DualStageIOMMUOps.pasid_alloc/free callbacks. > > Cc: Kevin Tian <kevin.tian@intel.com> > Cc: Jacob Pan <jacob.jun.pan@linux.intel.com> > Cc: Peter Xu <peterx@redhat.com> > Cc: Eric Auger <eric.auger@redhat.com> > Cc: Yi Sun <yi.y.sun@linux.intel.com> > Cc: David Gibson <david@gibson.dropbear.id.au> > Cc: Alex Williamson <alex.williamson@redhat.com> > Signed-off-by: Liu Yi L <yi.l.liu@intel.com> > --- > hw/vfio/common.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c > index a07824b..014f4e7 100644 > --- a/hw/vfio/common.c > +++ b/hw/vfio/common.c > @@ -1179,7 +1179,49 @@ static int vfio_get_iommu_type(VFIOContainer *container, > return -EINVAL; > } > > +static int vfio_ds_iommu_pasid_alloc(DualStageIOMMUObject *dsi_obj, > + uint32_t min, uint32_t max, uint32_t *pasid) > +{ > + VFIOContainer *container = container_of(dsi_obj, VFIOContainer, dsi_obj); > + struct vfio_iommu_type1_pasid_request req; > + unsigned long argsz; > + > + argsz = sizeof(req); > + req.argsz = argsz; > + req.flags = VFIO_IOMMU_PASID_ALLOC; > + req.alloc_pasid.min = min; > + req.alloc_pasid.max = max; > + > + if (ioctl(container->fd, VFIO_IOMMU_PASID_REQUEST, &req)) { > + error_report("%s: %d, alloc failed", __func__, -errno); > + return -errno; Note that errno is prone to change by other syscalls. Better cache it right after the ioctl. > + } > + *pasid = req.alloc_pasid.result; > + return 0; > +} > + > +static int vfio_ds_iommu_pasid_free(DualStageIOMMUObject *dsi_obj, > + uint32_t pasid) > +{ > + VFIOContainer *container = container_of(dsi_obj, VFIOContainer, dsi_obj); > + struct vfio_iommu_type1_pasid_request req; > + unsigned long argsz; > + > + argsz = sizeof(req); > + req.argsz = argsz; > + req.flags = VFIO_IOMMU_PASID_FREE; > + req.free_pasid = pasid; > + > + if (ioctl(container->fd, VFIO_IOMMU_PASID_REQUEST, &req)) { > + error_report("%s: %d, free failed", __func__, -errno); > + return -errno; Same here. > + } > + return 0; > +} > + > static struct DualStageIOMMUOps vfio_ds_iommu_ops = { > + .pasid_alloc = vfio_ds_iommu_pasid_alloc, > + .pasid_free = vfio_ds_iommu_pasid_free, > }; > > static int vfio_get_iommu_info(VFIOContainer *container, > -- > 2.7.4 >
> From: Peter Xu <peterx@redhat.com> > Sent: Wednesday, February 12, 2020 3:32 AM > To: Liu, Yi L <yi.l.liu@intel.com> > Subject: Re: [RFC v3 12/25] vfio/common: add pasid_alloc/free support > > On Wed, Jan 29, 2020 at 04:16:43AM -0800, Liu, Yi L wrote: > > From: Liu Yi L <yi.l.liu@intel.com> > > > > This patch adds VFIO pasid alloc/free support to allow host intercept > > in PASID allocation for VM by adding VFIO implementation of > > DualStageIOMMUOps.pasid_alloc/free callbacks. > > > > Cc: Kevin Tian <kevin.tian@intel.com> > > Cc: Jacob Pan <jacob.jun.pan@linux.intel.com> > > Cc: Peter Xu <peterx@redhat.com> > > Cc: Eric Auger <eric.auger@redhat.com> > > Cc: Yi Sun <yi.y.sun@linux.intel.com> > > Cc: David Gibson <david@gibson.dropbear.id.au> > > Cc: Alex Williamson <alex.williamson@redhat.com> > > Signed-off-by: Liu Yi L <yi.l.liu@intel.com> > > --- > > hw/vfio/common.c | 42 > ++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 42 insertions(+) > > > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c index > > a07824b..014f4e7 100644 > > --- a/hw/vfio/common.c > > +++ b/hw/vfio/common.c > > @@ -1179,7 +1179,49 @@ static int vfio_get_iommu_type(VFIOContainer > *container, > > return -EINVAL; > > } > > > > +static int vfio_ds_iommu_pasid_alloc(DualStageIOMMUObject *dsi_obj, > > + uint32_t min, uint32_t max, uint32_t *pasid) > > +{ > > + VFIOContainer *container = container_of(dsi_obj, VFIOContainer, dsi_obj); > > + struct vfio_iommu_type1_pasid_request req; > > + unsigned long argsz; > > + > > + argsz = sizeof(req); > > + req.argsz = argsz; > > + req.flags = VFIO_IOMMU_PASID_ALLOC; > > + req.alloc_pasid.min = min; > > + req.alloc_pasid.max = max; > > + > > + if (ioctl(container->fd, VFIO_IOMMU_PASID_REQUEST, &req)) { > > + error_report("%s: %d, alloc failed", __func__, -errno); > > + return -errno; > > Note that errno is prone to change by other syscalls. Better cache it right after > the ioctl. > > > + } > > + *pasid = req.alloc_pasid.result; > > + return 0; > > +} > > + > > +static int vfio_ds_iommu_pasid_free(DualStageIOMMUObject *dsi_obj, > > + uint32_t pasid) { > > + VFIOContainer *container = container_of(dsi_obj, VFIOContainer, dsi_obj); > > + struct vfio_iommu_type1_pasid_request req; > > + unsigned long argsz; > > + > > + argsz = sizeof(req); > > + req.argsz = argsz; > > + req.flags = VFIO_IOMMU_PASID_FREE; > > + req.free_pasid = pasid; > > + > > + if (ioctl(container->fd, VFIO_IOMMU_PASID_REQUEST, &req)) { > > + error_report("%s: %d, free failed", __func__, -errno); > > + return -errno; > > Same here. Got the two comments. Thanks, Regards, Yi Liu
diff --git a/hw/vfio/common.c b/hw/vfio/common.c index a07824b..014f4e7 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -1179,7 +1179,49 @@ static int vfio_get_iommu_type(VFIOContainer *container, return -EINVAL; } +static int vfio_ds_iommu_pasid_alloc(DualStageIOMMUObject *dsi_obj, + uint32_t min, uint32_t max, uint32_t *pasid) +{ + VFIOContainer *container = container_of(dsi_obj, VFIOContainer, dsi_obj); + struct vfio_iommu_type1_pasid_request req; + unsigned long argsz; + + argsz = sizeof(req); + req.argsz = argsz; + req.flags = VFIO_IOMMU_PASID_ALLOC; + req.alloc_pasid.min = min; + req.alloc_pasid.max = max; + + if (ioctl(container->fd, VFIO_IOMMU_PASID_REQUEST, &req)) { + error_report("%s: %d, alloc failed", __func__, -errno); + return -errno; + } + *pasid = req.alloc_pasid.result; + return 0; +} + +static int vfio_ds_iommu_pasid_free(DualStageIOMMUObject *dsi_obj, + uint32_t pasid) +{ + VFIOContainer *container = container_of(dsi_obj, VFIOContainer, dsi_obj); + struct vfio_iommu_type1_pasid_request req; + unsigned long argsz; + + argsz = sizeof(req); + req.argsz = argsz; + req.flags = VFIO_IOMMU_PASID_FREE; + req.free_pasid = pasid; + + if (ioctl(container->fd, VFIO_IOMMU_PASID_REQUEST, &req)) { + error_report("%s: %d, free failed", __func__, -errno); + return -errno; + } + return 0; +} + static struct DualStageIOMMUOps vfio_ds_iommu_ops = { + .pasid_alloc = vfio_ds_iommu_pasid_alloc, + .pasid_free = vfio_ds_iommu_pasid_free, }; static int vfio_get_iommu_info(VFIOContainer *container,