[RFC PATCH 1/9] vfio: add mmap maple tree to vfio

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

 



add mmap maple tree for vfio_device_file, this allows vfio devices to
create per mmap request options. the vfio device needs to
insert/allocate the region range offset & size and make it accessible
for the user, probably when the user is calling
DEVICE_GET_REGION_INFO, and then vfio uses the maple_tree to find the
entry (vfio_mmap) needed for mmap op, this adds the vfio_mmap_init &
vfio_mmap_free for initialization and freeing the entry, the freeing
is done through the free callback in the vfio_mmap_ops, which
vfio_devices should implement if they are allocating an entry.

Signed-off-by: Mahmoud Adam <mngyadam@xxxxxxxxx>
---
I didn't find a situation where we would need to use ref counting for
now, so I didn't implement it, I think most cases are already handled
by file ref counting, but maybe I'm overlooking something here.

 drivers/vfio/vfio.h      |  1 +
 drivers/vfio/vfio_main.c | 29 +++++++++++++++++++++++++++++
 include/linux/vfio.h     | 17 +++++++++++++++++
 3 files changed, 47 insertions(+)

diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index 50128da18bcaf..3f0cf2dd41116 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -19,6 +19,7 @@ struct vfio_container;
 struct vfio_device_file {
 	struct vfio_device *device;
 	struct vfio_group *group;
+	struct maple_tree mmap_mt;
 
 	u8 access_granted;
 	u32 devid; /* only valid when iommufd is valid */
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 1fd261efc582d..4c4af4de60d12 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -39,6 +39,7 @@
 #include <linux/interval_tree.h>
 #include <linux/iova_bitmap.h>
 #include <linux/iommufd.h>
+#include <linux/maple_tree.h>
 #include "vfio.h"
 
 #define DRIVER_VERSION	"0.3"
@@ -498,6 +499,7 @@ vfio_allocate_device_file(struct vfio_device *device)
 
 	df->device = device;
 	spin_lock_init(&df->kvm_ref_lock);
+	mt_init_flags(&df->mmap_mt, MT_FLAGS_ALLOC_RANGE);
 
 	return df;
 }
@@ -622,6 +624,25 @@ static inline void vfio_device_pm_runtime_put(struct vfio_device *device)
 		pm_runtime_put(dev);
 }
 
+void vfio_mmap_init(struct vfio_device *vdev, struct vfio_mmap *vmmap,
+		    u32 region_flags, u64 offset, u64 size,
+		    struct vfio_mmap_ops *ops)
+{
+	vmmap->owner = vdev;
+	vmmap->offset = offset;
+	vmmap->ops = ops;
+	vmmap->size = size;
+	vmmap->region_flags = region_flags;
+}
+EXPORT_SYMBOL_GPL(vfio_mmap_init);
+
+void vfio_mmap_free(struct vfio_mmap *vmmap)
+{
+	if (vmmap->ops && vmmap->ops->free)
+		vmmap->ops->free(vmmap);
+}
+EXPORT_SYMBOL_GPL(vfio_mmap_free);
+
 /*
  * VFIO Device fd
  */
@@ -629,14 +650,22 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep)
 {
 	struct vfio_device_file *df = filep->private_data;
 	struct vfio_device *device = df->device;
+	struct vfio_mmap *vmmap;
+	unsigned long index = 0;
 
 	if (df->group)
 		vfio_df_group_close(df);
 	else
 		vfio_df_unbind_iommufd(df);
 
+	mt_for_each(&df->mmap_mt, vmmap, index, ULONG_MAX) {
+		mtree_erase(&df->mmap_mt, index);
+		vfio_mmap_free(vmmap);
+	}
+
 	vfio_device_put_registration(device);
 
+	mtree_destroy(&df->mmap_mt);
 	kfree(df);
 
 	return 0;
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 707b00772ce1f..6e0aca05aa406 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -80,6 +80,19 @@ struct vfio_device {
 #endif
 };
 
+struct vfio_mmap {
+	struct vfio_device *owner;
+	u64 offset;
+	u64 size;
+	u32 region_flags;
+	struct vfio_mmap_ops *ops;
+};
+
+struct vfio_mmap_ops {
+	void	(*free)(struct vfio_mmap *vmmap);
+};
+
+
 /**
  * struct vfio_device_ops - VFIO bus driver device callbacks
  *
@@ -338,6 +351,10 @@ int vfio_pin_pages(struct vfio_device *device, dma_addr_t iova,
 void vfio_unpin_pages(struct vfio_device *device, dma_addr_t iova, int npage);
 int vfio_dma_rw(struct vfio_device *device, dma_addr_t iova,
 		void *data, size_t len, bool write);
+void vfio_mmap_init(struct vfio_device *vdev, struct vfio_mmap *vmmap,
+		    u32 region_flags, u64 offset, u64 size,
+		    struct vfio_mmap_ops *ops);
+void vfio_mmap_free(struct vfio_mmap *vmmap);
 
 /*
  * Sub-module helpers
-- 
2.47.3




Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597





[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