Yi, On 3/30/20 6:24 AM, Liu Yi L wrote: > This patch defines vfio_host_iommu_context_info, implements the PASID > alloc/free hooks defined in HostIOMMUContextClass. > > 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> > Cc: Alex Williamson <alex.williamson@xxxxxxxxxx> > Signed-off-by: Liu Yi L <yi.l.liu@xxxxxxxxx> > --- > hw/vfio/common.c | 69 +++++++++++++++++++++++++++++++++++ > include/hw/iommu/host_iommu_context.h | 3 ++ > include/hw/vfio/vfio-common.h | 4 ++ > 3 files changed, 76 insertions(+) > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c > index c276732..5f3534d 100644 > --- a/hw/vfio/common.c > +++ b/hw/vfio/common.c > @@ -1179,6 +1179,53 @@ static int vfio_get_iommu_type(VFIOContainer *container, > return -EINVAL; > } > > +static int vfio_host_iommu_ctx_pasid_alloc(HostIOMMUContext *iommu_ctx, > + uint32_t min, uint32_t max, > + uint32_t *pasid) > +{ > + VFIOContainer *container = container_of(iommu_ctx, > + VFIOContainer, iommu_ctx); > + struct vfio_iommu_type1_pasid_request req; > + unsigned long argsz; you can easily avoid using argsz variable > + 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); better use %m directly or strerror(errno) also include vbasedev->name? > + return ret; > + } > + *pasid = req.alloc_pasid.result; > + return 0; > +} > + > +static int vfio_host_iommu_ctx_pasid_free(HostIOMMUContext *iommu_ctx, > + uint32_t pasid) > +{ > + VFIOContainer *container = container_of(iommu_ctx, > + VFIOContainer, iommu_ctx); > + struct vfio_iommu_type1_pasid_request req; > + unsigned long argsz; same > + 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); same > + return ret; > + } > + return 0; > +} > + > static int vfio_init_container(VFIOContainer *container, int group_fd, > Error **errp) > { > @@ -1791,3 +1838,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_iommu_ctx_pasid_alloc; > + hicxc->pasid_free = vfio_host_iommu_ctx_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, Ah OK This is the object inheriting from the abstract TYPE_HOST_IOMMU_CONTEXT. I initially thought VTDHostIOMMUContext was, sorry for the misunderstanding. Do you expect other HostIOMMUContext backends? Given the name and ops, it looks really related to VFIO? Thanks Eric > +}; > + > +static void vfio_register_types(void) > +{ > + type_register_static(&vfio_host_iommu_context_info); > +} > + > +type_init(vfio_register_types) > diff --git a/include/hw/iommu/host_iommu_context.h b/include/hw/iommu/host_iommu_context.h > index 35c4861..227c433 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..0b07303 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 iommu_ctx; > Error *error; > bool initialized; > unsigned long pgsizes; >