@@ -1528,6 +1528,17 @@ static int bind_pasid_tbl_fn(struct device *dev, void *data)
return ret;
}
+static int do_tlb_inv_fn(struct device *dev, void *data)
+{
+ int ret = 0;
+ struct vfio_svm_task *task = data;
+ struct tlb_invalidate_info *inv_info;
+
+ inv_info = task->payload;
+ ret = iommu_do_invalidate(task->domain, dev, inv_info);
+ return ret;
+}
+
static int vfio_do_svm_task(struct vfio_iommu *iommu, void *data,
int (*fn)(struct device *, void *))
{
@@ -1654,6 +1665,21 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
}
kfree(data);
return ret;
+ } else if (cmd == VFIO_IOMMU_TLB_INVALIDATE) {
+ struct vfio_iommu_tlb_invalidate hdr;
+ u8 *data = NULL;
+ int ret = 0;
+
+ minsz = offsetofend(struct vfio_iommu_tlb_invalidate, length);
+ if (copy_from_user(&hdr, (void __user *)arg, minsz))
+ return -EFAULT;
+ if (hdr.length == 0)
+ return -EINVAL;
+ data = memdup_user((void __user *)(arg + minsz),
+ hdr.length);
+ ret = vfio_do_svm_task(iommu, data, do_tlb_inv_fn);
+ kfree(data);
+ return ret;
}
return -ENOTTY;