diff mbox

[Intel-gfx,RFC,8/9] drm/i915/gvt: Introduce new VFIO ioctl for mdev device dirty page sync

Message ID 1491301977-24481-9-git-send-email-yulei.zhang@intel.com
State New
Headers show

Commit Message

Zhang, Yulei April 4, 2017, 10:32 a.m. UTC
Add new vfio ioctl VFIO_DEVICE_PCI_GET_DIRTY_BITMAP to fetch the dirty
page bitmap from mdev device driver for data sync during live migration.

Signed-off-by: Yulei Zhang <yulei.zhang@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 33 +++++++++++++++++++++++++++++++++
 include/uapi/linux/vfio.h        | 14 ++++++++++++++
 2 files changed, 47 insertions(+)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index ac327f7..e9f11a9 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -919,6 +919,24 @@  static int intel_vgpu_set_irqs(struct intel_vgpu *vgpu, uint32_t flags,
 	return func(vgpu, index, start, count, flags, data);
 }
 
+static void intel_vgpu_update_dirty_bitmap(struct intel_vgpu *vgpu, u64 start_addr,
+                                           u64 page_nr, void *bitmap)
+{
+	u64 gfn = start_addr >> GTT_PAGE_SHIFT;
+	struct intel_vgpu_guest_page *p;
+	int i;
+
+	for (i = 0; i < page_nr; i++) {
+		hash_for_each_possible(vgpu->gtt.guest_page_hash_table,
+				       p, node, gfn) {
+			if (p->gfn == gfn)
+				set_bit(i, bitmap);
+		}
+		gfn++;
+	}
+
+}
+
 static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
 			     unsigned long arg)
 {
@@ -1156,6 +1174,21 @@  static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
 			intel_gvt_ops->vgpu_deactivate(vgpu);
 		else
 			intel_gvt_ops->vgpu_activate(vgpu);
+	} else if (cmd == VFIO_DEVICE_PCI_GET_DIRTY_BITMAP) {
+		struct vfio_pci_get_dirty_bitmap d;
+		unsigned long bitmap_sz;
+		unsigned *bitmap;
+		minsz = offsetofend(struct vfio_pci_get_dirty_bitmap, page_nr);
+		if (copy_from_user(&d, (void __user *)arg, minsz))
+			return -EFAULT;
+		bitmap_sz = (BITS_TO_LONGS(d.page_nr) + 1) * sizeof(unsigned long);
+		bitmap = vzalloc(bitmap_sz);
+		intel_vgpu_update_dirty_bitmap(vgpu, d.start_addr, d.page_nr, bitmap);
+		if (copy_to_user((void __user*)arg + minsz, bitmap, bitmap_sz)) {
+			vfree(bitmap);
+			return -EFAULT;
+		}
+		vfree(bitmap);
 	}
 
 	return 0;
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 4bb057d..544cf93 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -518,6 +518,20 @@  struct vfio_pci_status_set{
 
 #define VFIO_DEVICE_PCI_STATUS_SET	_IO(VFIO_TYPE, VFIO_BASE + 14)
 
+/**
+ * VFIO_DEVICE_PCI_GET_DIRTY_BITMAP - _IOW(VFIO_TYPE, VFIO_BASE + 15,
+ *				    struct vfio_pci_get_dirty_bitmap)
+ *
+ * Return: 0 on success, -errno on failure.
+ */
+struct vfio_pci_get_dirty_bitmap{
+	__u64	       start_addr;
+	__u64	       page_nr;
+	__u8           dirty_bitmap[];
+};
+
+#define VFIO_DEVICE_PCI_GET_DIRTY_BITMAP _IO(VFIO_TYPE, VFIO_BASE + 15)
+
 /* -------- API for Type1 VFIO IOMMU -------- */
 
 /**