[PATCH V1 7/8] vfio: change dma owner

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Define the VFIO_DMA_OWNER extension.  It indicates support for the
redefined VFIO_DMA_MAP_FLAG_VADDR, and the new VFIO_CHANGE_DMA_OWNER
ioctl, defined as:

 Change ownership of all dma mappings to the calling task, including
 count of locked pages subject to RLIMIT_MEMLOCK.  The new task's address
 space is used to translate virtual to physical addresses for all future
 requests, including as those issued by mediated devices. For all mappings,
 the vaddr must be the same in the old and new address space, or can be
 changed in the new address space by using VFIO_DMA_MAP_FLAG_VADDR.

See vfio.h for more details.

Signed-off-by: Steve Sistare <steven.sistare@xxxxxxxxxx>
---
 drivers/vfio/container.c  | 18 ++++++++++++++++++
 drivers/vfio/vfio.h       |  1 +
 include/uapi/linux/vfio.h | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/drivers/vfio/container.c b/drivers/vfio/container.c
index b660adc..7e78593 100644
--- a/drivers/vfio/container.c
+++ b/drivers/vfio/container.c
@@ -468,6 +468,21 @@ static int vfio_fops_mmap(struct file *filep, struct vm_area_struct *vma)
 	return 0;
 }
 
+static int vfio_change_dma_owner(struct vfio_container *container,
+				 struct file *filep)
+{
+	struct vfio_iommu_driver *driver = container->iommu_driver;
+	int ret;
+
+	if (!driver || !driver->ops->change_dma_owner)
+		return -ENOTTY;
+
+	ret = vfio_register_dma_task(container, filep);
+	if (!ret)
+		ret = driver->ops->change_dma_owner(container->iommu_data);
+	return ret;
+}
+
 static long vfio_fops_unl_ioctl(struct file *filep,
 				unsigned int cmd, unsigned long arg)
 {
@@ -489,6 +504,9 @@ static long vfio_fops_unl_ioctl(struct file *filep,
 	case VFIO_SET_IOMMU:
 		ret = vfio_ioctl_set_iommu(container, arg);
 		break;
+	case VFIO_CHANGE_DMA_OWNER:
+		ret = vfio_change_dma_owner(container, filep);
+		break;
 	case VFIO_IOMMU_MAP_DMA:
 		ret = vfio_register_dma_task(container, filep);
 		if (ret)
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index 0cf3cfe..999a7b0 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -92,6 +92,7 @@ struct vfio_iommu_driver_ops {
 				  void *data, size_t count, bool write);
 	struct iommu_domain *(*group_iommu_domain)(void *iommu_data,
 						   struct iommu_group *group);
+	int		(*change_dma_owner)(void *iommu_data);
 	void		(*close_dma_owner)(void *iommu_data);
 };
 
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 8b7c1ed..8074d80 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -53,6 +53,11 @@
 #define VFIO_UPDATE_VADDR		10
 
 /*
+ * Supports VFIO_CHANGE_DMA_OWNER and VFIO_DMA_MAP_FLAG_VADDR.
+ */
+#define VFIO_DMA_OWNER			11
+
+/*
  * The IOCTL interface is designed for extensibility by embedding the
  * structure length (argsz) and flags into structures passed between
  * kernel and userspace.  We therefore use the _IO() macro for these
@@ -128,6 +133,33 @@ struct vfio_info_cap_header {
  */
 #define VFIO_SET_IOMMU			_IO(VFIO_TYPE, VFIO_BASE + 2)
 
+/**
+ * VFIO_CHANGE_DMA_OWNER		_IO(VFIO_TYPE, VFIO_BASE + 22)
+ *
+ * Change ownership of all dma mappings to the calling task, including
+ * count of locked pages subject to RLIMIT_MEMLOCK.  The new task's address
+ * space is used to translate virtual to physical addresses for all future
+ * requests, including as those issued by mediated devices.  For all mappings,
+ * the vaddr must be the same in the old and new address space, or can be
+ * changed in the new address space by using VFIO_DMA_MAP_FLAG_VADDR, but in
+ * both cases the old vaddr and address space must map to the same memory
+ * object as the new vaddr and address space.  Length and access permissions
+ * cannot be changed, and the object must be mapped shared.  Tasks must not
+ * modify the old or new address space over the affected ranges during this
+ * ioctl, else differences might not be detected, and dma may target the wrong
+ * user pages.
+ *
+ * Return:
+ *	      0: success
+ *       -ESRCH: owning task is dead.
+ *	-ENOMEM: Out of memory, or RLIMIT_MEMLOCK is too low.
+ *	 -ENXIO: Memory object does not match or is not shared.
+ *	-EINVAL: a new vaddr was provided for some but not all mappings.
+ *
+ * Availability: with VFIO_DMA_OWNER extension.
+ */
+#define VFIO_CHANGE_DMA_OWNER		_IO(VFIO_TYPE, VFIO_BASE + 22)
+
 /* -------- IOCTLs for GROUP file descriptors (/dev/vfio/$GROUP) -------- */
 
 /**
-- 
1.8.3.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux