|
@@ -58,12 +58,18 @@ module_param_named(disable_hugepages,
|
|
|
MODULE_PARM_DESC(disable_hugepages,
|
|
MODULE_PARM_DESC(disable_hugepages,
|
|
|
"Disable VFIO IOMMU support for IOMMU hugepages.");
|
|
"Disable VFIO IOMMU support for IOMMU hugepages.");
|
|
|
|
|
|
|
|
|
|
+static unsigned int dma_entry_limit __read_mostly = U16_MAX;
|
|
|
|
|
+module_param_named(dma_entry_limit, dma_entry_limit, uint, 0644);
|
|
|
|
|
+MODULE_PARM_DESC(dma_entry_limit,
|
|
|
|
|
+ "Maximum number of user DMA mappings per container (65535).");
|
|
|
|
|
+
|
|
|
struct vfio_iommu {
|
|
struct vfio_iommu {
|
|
|
struct list_head domain_list;
|
|
struct list_head domain_list;
|
|
|
struct vfio_domain *external_domain; /* domain for external user */
|
|
struct vfio_domain *external_domain; /* domain for external user */
|
|
|
struct mutex lock;
|
|
struct mutex lock;
|
|
|
struct rb_root dma_list;
|
|
struct rb_root dma_list;
|
|
|
struct blocking_notifier_head notifier;
|
|
struct blocking_notifier_head notifier;
|
|
|
|
|
+ unsigned int dma_avail;
|
|
|
bool v2;
|
|
bool v2;
|
|
|
bool nesting;
|
|
bool nesting;
|
|
|
};
|
|
};
|
|
@@ -836,6 +842,7 @@ static void vfio_remove_dma(struct vfio_iommu *iommu, struct vfio_dma *dma)
|
|
|
vfio_unlink_dma(iommu, dma);
|
|
vfio_unlink_dma(iommu, dma);
|
|
|
put_task_struct(dma->task);
|
|
put_task_struct(dma->task);
|
|
|
kfree(dma);
|
|
kfree(dma);
|
|
|
|
|
+ iommu->dma_avail++;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static unsigned long vfio_pgsize_bitmap(struct vfio_iommu *iommu)
|
|
static unsigned long vfio_pgsize_bitmap(struct vfio_iommu *iommu)
|
|
@@ -1110,12 +1117,18 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
|
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (!iommu->dma_avail) {
|
|
|
|
|
+ ret = -ENOSPC;
|
|
|
|
|
+ goto out_unlock;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
dma = kzalloc(sizeof(*dma), GFP_KERNEL);
|
|
dma = kzalloc(sizeof(*dma), GFP_KERNEL);
|
|
|
if (!dma) {
|
|
if (!dma) {
|
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ iommu->dma_avail--;
|
|
|
dma->iova = iova;
|
|
dma->iova = iova;
|
|
|
dma->vaddr = vaddr;
|
|
dma->vaddr = vaddr;
|
|
|
dma->prot = prot;
|
|
dma->prot = prot;
|
|
@@ -1612,6 +1625,7 @@ static void *vfio_iommu_type1_open(unsigned long arg)
|
|
|
|
|
|
|
|
INIT_LIST_HEAD(&iommu->domain_list);
|
|
INIT_LIST_HEAD(&iommu->domain_list);
|
|
|
iommu->dma_list = RB_ROOT;
|
|
iommu->dma_list = RB_ROOT;
|
|
|
|
|
+ iommu->dma_avail = dma_entry_limit;
|
|
|
mutex_init(&iommu->lock);
|
|
mutex_init(&iommu->lock);
|
|
|
BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier);
|
|
BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier);
|
|
|
|
|
|