diff mbox series

[RFC,v3,12/25] vfio/common: add pasid_alloc/free support

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

Commit Message

Yi Liu Jan. 29, 2020, 12:16 p.m. UTC
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(+)

Comments

Peter Xu Feb. 11, 2020, 7:31 p.m. UTC | #1
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
>
Yi Liu Feb. 12, 2020, 7:20 a.m. UTC | #2
> 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 mbox series

Patch

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,