On Wed, 2014-09-24 at 10:21 +0100, Will Deacon wrote:
> VFIO allows devices to be safely handed off to userspace by putting
> them behind an IOMMU configured to ensure DMA and interrupt isolation.
> This enables userspace KVM clients, such as kvmtool and qemu, to further
> map the device into a virtual machine.
> 
> With IOMMUs such as the ARM SMMU, it is then possible to provide SMMU
> translation services to the guest operating system, which are nested
> with the existing translation installed by VFIO. However, enabling this
> feature means that the IOMMU driver must be informed that the VFIO domain
> is being created for the purposes of nested translation.
> 
> This patch adds a new IOMMU type (VFIO_TYPE1_NESTING_IOMMU) to the VFIO
> type-1 driver. The new IOMMU type acts identically to the
> VFIO_TYPE1v2_IOMMU type, but additionally sets the DOMAIN_ATTR_NESTING
> attribute on its IOMMU domains.
> 
> Cc: Joerg Roedel <[email protected]>
> Cc: Alex Williamson <[email protected]>
> Signed-off-by: Will Deacon <[email protected]>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 29 +++++++++++++++++++++++------
>  include/uapi/linux/vfio.h       |  3 +++
>  2 files changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index 0734fbe5b651..d15b00700a31 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -57,7 +57,8 @@ struct vfio_iommu {
>       struct list_head        domain_list;
>       struct mutex            lock;
>       struct rb_root          dma_list;
> -     bool v2;
> +     bool                    v2;
> +     bool                    nesting;
>  };
>  
>  struct vfio_domain {
> @@ -671,7 +672,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
>       struct vfio_group *group, *g;
>       struct vfio_domain *domain, *d;
>       struct bus_type *bus = NULL;
> -     int ret;
> +     int ret, attr = 1;
>  
>       mutex_lock(&iommu->lock);
>  
> @@ -705,6 +706,13 @@ static int vfio_iommu_type1_attach_group(void 
> *iommu_data,
>               goto out_free;
>       }
>  
> +     if (iommu->nesting) {

nit, attr declaration could be moved here

> +             ret = iommu_domain_set_attr(domain->domain, DOMAIN_ATTR_NESTING,
> +                                         &attr);
> +             if (ret)
> +                     goto out_domain;
> +     }
> +
>       ret = iommu_attach_group(domain->domain, iommu_group);
>       if (ret)
>               goto out_domain;
> @@ -819,17 +827,25 @@ static void *vfio_iommu_type1_open(unsigned long arg)
>  {
>       struct vfio_iommu *iommu;
>  
> -     if (arg != VFIO_TYPE1_IOMMU && arg != VFIO_TYPE1v2_IOMMU)
> -             return ERR_PTR(-EINVAL);
> -
>       iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
>       if (!iommu)
>               return ERR_PTR(-ENOMEM);
>  
> +     switch (arg) {
> +     case VFIO_TYPE1_IOMMU:
> +             break;
> +     case VFIO_TYPE1_NESTING_IOMMU:
> +             iommu->nesting = true;
> +     case VFIO_TYPE1v2_IOMMU:
> +             iommu->v2 = true;
> +             break;
> +     default:

Leaks iommu

> +             return ERR_PTR(-EINVAL);
> +     }
> +
>       INIT_LIST_HEAD(&iommu->domain_list);
>       iommu->dma_list = RB_ROOT;
>       mutex_init(&iommu->lock);
> -     iommu->v2 = (arg == VFIO_TYPE1v2_IOMMU);
>  
>       return iommu;
>  }
> @@ -885,6 +901,7 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>               switch (arg) {
>               case VFIO_TYPE1_IOMMU:
>               case VFIO_TYPE1v2_IOMMU:
> +             case VFIO_TYPE1_NESTING_IOMMU:
>                       return 1;
>               case VFIO_DMA_CC_IOMMU:
>                       if (!iommu)
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index 6612974c64bf..29715d27548f 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -33,6 +33,9 @@
>  /* Check if EEH is supported */
>  #define VFIO_EEH                     5
>  
> +/* Two-stage IOMMU */
> +#define VFIO_TYPE1_NESTING_IOMMU     6       /* Implies v2 */
> +
>  /*
>   * The IOCTL interface is designed for extensibility by embedding the
>   * structure length (argsz) and flags into structures passed between



_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to