diff mbox series

[v1,08/22] vfio: init HostIOMMUContext per-container

Message ID 1584880579-12178-9-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 March 22, 2020, 12:36 p.m. UTC
After confirming dual stage DMA translation support with kernel by
checking VFIO_TYPE1_NESTING_IOMMU, VFIO inits HostIOMMUContet instance
and exposes it to PCI layer. Thus vIOMMU emualtors may make use of
such capability by leveraging the methods provided by HostIOMMUContext.

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                      | 80 +++++++++++++++++++++++++++++++++++
 hw/vfio/pci.c                         | 13 ++++++
 include/hw/iommu/host_iommu_context.h |  3 ++
 include/hw/vfio/vfio-common.h         |  4 ++
 4 files changed, 100 insertions(+)

Comments

Yi Liu March 24, 2020, 1:03 p.m. UTC | #1
> From: Peter Xu <peterx@redhat.com>
> Sent: Tuesday, March 24, 2020 5:40 AM
> To: Liu, Yi L <yi.l.liu@intel.com>
> Subject: Re: [PATCH v1 08/22] vfio: init HostIOMMUContext per-container
> 
> On Sun, Mar 22, 2020 at 05:36:05AM -0700, Liu Yi L wrote:
> > After confirming dual stage DMA translation support with kernel by
> > checking VFIO_TYPE1_NESTING_IOMMU, VFIO inits HostIOMMUContet instance
> > and exposes it to PCI layer. Thus vIOMMU emualtors may make use of
> > such capability by leveraging the methods provided by HostIOMMUContext.
> >
> > 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                      | 80 +++++++++++++++++++++++++++++++++++
> >  hw/vfio/pci.c                         | 13 ++++++
> >  include/hw/iommu/host_iommu_context.h |  3 ++
> >  include/hw/vfio/vfio-common.h         |  4 ++
> >  4 files changed, 100 insertions(+)
> >
> > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > index c276732..e4f5f10 100644
> > --- a/hw/vfio/common.c
> > +++ b/hw/vfio/common.c
> > @@ -1179,10 +1179,55 @@ static int vfio_get_iommu_type(VFIOContainer
> *container,
> >      return -EINVAL;
> >  }
> >
> > +static int vfio_host_icx_pasid_alloc(HostIOMMUContext *host_icx,
> 
> I'm not sure about Alex, but ... icx is confusing to me.  Maybe "ctx"
> as you always used?

At first I used vfio_host_iommu_ctx_pasid_alloc(), found it is long, so I
switched to "icx" which means iommu_context. Maybe the former one
looks better as it gives more precise info.

Regards,
Yi Liu
Peter Xu March 24, 2020, 2:45 p.m. UTC | #2
On Tue, Mar 24, 2020 at 01:03:28PM +0000, Liu, Yi L wrote:
> > From: Peter Xu <peterx@redhat.com>
> > Sent: Tuesday, March 24, 2020 5:40 AM
> > To: Liu, Yi L <yi.l.liu@intel.com>
> > Subject: Re: [PATCH v1 08/22] vfio: init HostIOMMUContext per-container
> > 
> > On Sun, Mar 22, 2020 at 05:36:05AM -0700, Liu Yi L wrote:
> > > After confirming dual stage DMA translation support with kernel by
> > > checking VFIO_TYPE1_NESTING_IOMMU, VFIO inits HostIOMMUContet instance
> > > and exposes it to PCI layer. Thus vIOMMU emualtors may make use of
> > > such capability by leveraging the methods provided by HostIOMMUContext.
> > >
> > > 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                      | 80 +++++++++++++++++++++++++++++++++++
> > >  hw/vfio/pci.c                         | 13 ++++++
> > >  include/hw/iommu/host_iommu_context.h |  3 ++
> > >  include/hw/vfio/vfio-common.h         |  4 ++
> > >  4 files changed, 100 insertions(+)
> > >
> > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > > index c276732..e4f5f10 100644
> > > --- a/hw/vfio/common.c
> > > +++ b/hw/vfio/common.c
> > > @@ -1179,10 +1179,55 @@ static int vfio_get_iommu_type(VFIOContainer
> > *container,
> > >      return -EINVAL;
> > >  }
> > >
> > > +static int vfio_host_icx_pasid_alloc(HostIOMMUContext *host_icx,
> > 
> > I'm not sure about Alex, but ... icx is confusing to me.  Maybe "ctx"
> > as you always used?
> 
> At first I used vfio_host_iommu_ctx_pasid_alloc(), found it is long, so I
> switched to "icx" which means iommu_context. Maybe the former one
> looks better as it gives more precise info.

vfio_host_iommu_ctx_pasid_alloc() isn't that bad imho.  I'll omit the
"ctx" if I want to make it even shorter, but "icx" might be ambiguous.

Thanks,
Yi Liu March 25, 2020, 9:30 a.m. UTC | #3
> From: Peter Xu <peterx@redhat.com>
> Sent: Tuesday, March 24, 2020 10:46 PM
> To: Liu, Yi L <yi.l.liu@intel.com>
> Subject: Re: [PATCH v1 08/22] vfio: init HostIOMMUContext per-container
> 
> On Tue, Mar 24, 2020 at 01:03:28PM +0000, Liu, Yi L wrote:
> > > From: Peter Xu <peterx@redhat.com>
> > > Sent: Tuesday, March 24, 2020 5:40 AM
> > > To: Liu, Yi L <yi.l.liu@intel.com>
> > > Subject: Re: [PATCH v1 08/22] vfio: init HostIOMMUContext
> > > per-container
> > >
> > > On Sun, Mar 22, 2020 at 05:36:05AM -0700, Liu Yi L wrote:
> > > > After confirming dual stage DMA translation support with kernel by
> > > > checking VFIO_TYPE1_NESTING_IOMMU, VFIO inits HostIOMMUContet
> > > > instance and exposes it to PCI layer. Thus vIOMMU emualtors may
> > > > make use of such capability by leveraging the methods provided by
> HostIOMMUContext.
> > > >
> > > > 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                      | 80
> +++++++++++++++++++++++++++++++++++
> > > >  hw/vfio/pci.c                         | 13 ++++++
> > > >  include/hw/iommu/host_iommu_context.h |  3 ++
> > > >  include/hw/vfio/vfio-common.h         |  4 ++
> > > >  4 files changed, 100 insertions(+)
> > > >
> > > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c index
> > > > c276732..e4f5f10 100644
> > > > --- a/hw/vfio/common.c
> > > > +++ b/hw/vfio/common.c
> > > > @@ -1179,10 +1179,55 @@ static int
> > > > vfio_get_iommu_type(VFIOContainer
> > > *container,
> > > >      return -EINVAL;
> > > >  }
> > > >
> > > > +static int vfio_host_icx_pasid_alloc(HostIOMMUContext *host_icx,
> > >
> > > I'm not sure about Alex, but ... icx is confusing to me.  Maybe "ctx"
> > > as you always used?
> >
> > At first I used vfio_host_iommu_ctx_pasid_alloc(), found it is long,
> > so I switched to "icx" which means iommu_context. Maybe the former one
> > looks better as it gives more precise info.
> 
> vfio_host_iommu_ctx_pasid_alloc() isn't that bad imho.  I'll omit the "ctx" if I want
> to make it even shorter, but "icx" might be ambiguous.

Got it. let me modify the prefix.

Regards,
Yi Liu
diff mbox series

Patch

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index c276732..e4f5f10 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1179,10 +1179,55 @@  static int vfio_get_iommu_type(VFIOContainer *container,
     return -EINVAL;
 }
 
+static int vfio_host_icx_pasid_alloc(HostIOMMUContext *host_icx,
+                                  uint32_t min, uint32_t max, uint32_t *pasid)
+{
+    VFIOContainer *container = container_of(host_icx, VFIOContainer, host_icx);
+    struct vfio_iommu_type1_pasid_request req;
+    unsigned long argsz;
+    int ret;
+
+    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)) {
+        ret = -errno;
+        error_report("%s: %d, alloc failed", __func__, ret);
+        return ret;
+    }
+    *pasid = req.alloc_pasid.result;
+    return 0;
+}
+
+static int vfio_host_icx_pasid_free(HostIOMMUContext *host_icx,
+                                    uint32_t pasid)
+{
+    VFIOContainer *container = container_of(host_icx, VFIOContainer, host_icx);
+    struct vfio_iommu_type1_pasid_request req;
+    unsigned long argsz;
+    int ret;
+
+    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)) {
+        ret = -errno;
+        error_report("%s: %d, free failed", __func__, ret);
+        return ret;
+    }
+    return 0;
+}
+
 static int vfio_init_container(VFIOContainer *container, int group_fd,
                                Error **errp)
 {
     int iommu_type, ret;
+    uint64_t flags = 0;
 
     iommu_type = vfio_get_iommu_type(container, errp);
     if (iommu_type < 0) {
@@ -1210,6 +1255,18 @@  static int vfio_init_container(VFIOContainer *container, int group_fd,
         return -errno;
     }
 
+    if (iommu_type == VFIO_TYPE1_NESTING_IOMMU) {
+        /*
+         * TODO: config flags per host IOMMU nesting capability
+         * e.g. check if VFIO_TYPE1_NESTING_IOMMU supports PASID
+         * alloc/free
+         */
+        host_iommu_ctx_init(&container->host_icx,
+                            sizeof(container->host_icx),
+                            TYPE_VFIO_HOST_IOMMU_CONTEXT,
+                            flags);
+    }
+
     container->iommu_type = iommu_type;
     return 0;
 }
@@ -1456,6 +1513,7 @@  static void vfio_disconnect_container(VFIOGroup *group)
         }
 
         trace_vfio_disconnect_container(container->fd);
+        host_iommu_ctx_destroy(&container->host_icx);
         close(container->fd);
         g_free(container);
 
@@ -1791,3 +1849,25 @@  int vfio_eeh_as_op(AddressSpace *as, uint32_t op)
     }
     return vfio_eeh_container_op(container, op);
 }
+
+static void vfio_host_iommu_context_class_init(ObjectClass *klass,
+                                                       void *data)
+{
+    HostIOMMUContextClass *hicxc = HOST_IOMMU_CONTEXT_CLASS(klass);
+
+    hicxc->pasid_alloc = vfio_host_icx_pasid_alloc;
+    hicxc->pasid_free = vfio_host_icx_pasid_free;
+}
+
+static const TypeInfo vfio_host_iommu_context_info = {
+    .parent = TYPE_HOST_IOMMU_CONTEXT,
+    .name = TYPE_VFIO_HOST_IOMMU_CONTEXT,
+    .class_init = vfio_host_iommu_context_class_init,
+};
+
+static void vfio_register_types(void)
+{
+    type_register_static(&vfio_host_iommu_context_info);
+}
+
+type_init(vfio_register_types)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 5e75a95..f099df3 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2717,6 +2717,7 @@  static void vfio_realize(PCIDevice *pdev, Error **errp)
     VFIOPCIDevice *vdev = PCI_VFIO(pdev);
     VFIODevice *vbasedev_iter;
     VFIOGroup *group;
+    VFIOContainer *container;
     char *tmp, *subsys, group_path[PATH_MAX], *group_name;
     Error *err = NULL;
     ssize_t len;
@@ -3028,6 +3029,11 @@  static void vfio_realize(PCIDevice *pdev, Error **errp)
     vfio_register_req_notifier(vdev);
     vfio_setup_resetfn_quirk(vdev);
 
+    container = vdev->vbasedev.group->container;
+    if (container->host_icx.initialized) {
+        pci_device_set_iommu_context(pdev, &container->host_icx);
+    }
+
     return;
 
 out_deregister:
@@ -3072,9 +3078,16 @@  static void vfio_instance_finalize(Object *obj)
 static void vfio_exitfn(PCIDevice *pdev)
 {
     VFIOPCIDevice *vdev = PCI_VFIO(pdev);
+    VFIOContainer *container;
 
     vfio_unregister_req_notifier(vdev);
     vfio_unregister_err_notifier(vdev);
+
+    container = vdev->vbasedev.group->container;
+    if (container->host_icx.initialized) {
+        pci_device_unset_iommu_context(pdev);
+    }
+
     pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
     if (vdev->irqchip_change_notifier.notify) {
         kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier);
diff --git a/include/hw/iommu/host_iommu_context.h b/include/hw/iommu/host_iommu_context.h
index cfbf5ac..5f11a4c 100644
--- a/include/hw/iommu/host_iommu_context.h
+++ b/include/hw/iommu/host_iommu_context.h
@@ -33,6 +33,9 @@ 
 #define TYPE_HOST_IOMMU_CONTEXT "qemu:host-iommu-context"
 #define HOST_IOMMU_CONTEXT(obj) \
         OBJECT_CHECK(HostIOMMUContext, (obj), TYPE_HOST_IOMMU_CONTEXT)
+#define HOST_IOMMU_CONTEXT_CLASS(klass) \
+        OBJECT_CLASS_CHECK(HostIOMMUContextClass, (klass), \
+                         TYPE_HOST_IOMMU_CONTEXT)
 #define HOST_IOMMU_CONTEXT_GET_CLASS(obj) \
         OBJECT_GET_CLASS(HostIOMMUContextClass, (obj), \
                          TYPE_HOST_IOMMU_CONTEXT)
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index fd56420..532b78d 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -26,12 +26,15 @@ 
 #include "qemu/notify.h"
 #include "ui/console.h"
 #include "hw/display/ramfb.h"
+#include "hw/iommu/host_iommu_context.h"
 #ifdef CONFIG_LINUX
 #include <linux/vfio.h>
 #endif
 
 #define VFIO_MSG_PREFIX "vfio %s: "
 
+#define TYPE_VFIO_HOST_IOMMU_CONTEXT "qemu:vfio-host-iommu-context"
+
 enum {
     VFIO_DEVICE_TYPE_PCI = 0,
     VFIO_DEVICE_TYPE_PLATFORM = 1,
@@ -71,6 +74,7 @@  typedef struct VFIOContainer {
     MemoryListener listener;
     MemoryListener prereg_listener;
     unsigned iommu_type;
+    HostIOMMUContext host_icx;
     Error *error;
     bool initialized;
     unsigned long pgsizes;