|
@@ -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 {
|
|
@@ -705,6 +706,15 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
|
|
|
goto out_free;
|
|
|
}
|
|
|
|
|
|
+ if (iommu->nesting) {
|
|
|
+ int attr = 1;
|
|
|
+
|
|
|
+ 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 +829,26 @@ 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:
|
|
|
+ kfree(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 +904,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)
|