diff mbox

[v2,1/4] KVM: Dirty memory tracking for performant checkpointing solutions

Message ID CY1PR08MB19920AFC6DDF9E1F50BC21F5F0610@CY1PR08MB1992.namprd08.prod.outlook.com (mailing list archive)
State New, archived
Headers show

Commit Message

Cao, Lei Jan. 4, 2017, 8:41 p.m. UTC
Introduce new memory tracking ioctls to support performant
checkpointing solutions.

See patch 4 for details on the new ioctls.

Signed-off-by: Lei Cao <lei.cao@stratus.com>
---
 arch/x86/include/asm/kvm_host.h |  2 ++
 arch/x86/kvm/x86.c              |  3 +++
 include/uapi/linux/kvm.h        |  8 +++++++
 virt/kvm/kvm_main.c             | 47 ++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 59 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2e25038..6dfb14a 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -45,6 +45,8 @@ 
 
 #define KVM_PIO_PAGE_OFFSET 1
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2
+#define KVM_DIRTY_LOG_PAGE_OFFSET 3
+
 #define KVM_HALT_POLL_NS_DEFAULT 400000
 
 #define KVM_IRQCHIP_NUM_PINS  KVM_IOAPIC_NUM_PINS
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0b387d6..5707129 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2688,6 +2688,9 @@  int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_X2APIC_API:
 		r = KVM_X2APIC_API_VALID_FLAGS;
 		break;
+	case KVM_CAP_DIRTY_LOG_LIST:
+		r = KVM_DIRTY_LOG_PAGE_OFFSET;
+		break;
 	default:
 		r = 0;
 		break;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index cac48ed..05332de 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -871,6 +871,7 @@  struct kvm_ppc_smmu_info {
 #define KVM_CAP_S390_USER_INSTR0 130
 #define KVM_CAP_MSI_DEVID 131
 #define KVM_CAP_PPC_HTM 132
+#define KVM_CAP_DIRTY_LOG_LIST 133
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1282,6 +1283,13 @@  struct kvm_s390_ucas_mapping {
 /* Available with KVM_CAP_X86_SMM */
 #define KVM_SMI                   _IO(KVMIO,   0xb7)
 
+/* Set the per-vcpu dirty log size */
+#define KVM_SET_DIRTY_LOG_SIZE    _IOW(KVMIO, 0xc0, __u32)
+/* Rearm traps for all dirty pages */
+#define KVM_RESET_DIRTY_PAGES     _IO(KVMIO, 0xc1)
+/* Get the current dirty count */
+#define KVM_GET_DIRTY_COUNT       _IOR(KVMIO, 0xc2, __u32)
+
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3		(1 << 1)
 #define KVM_DEV_ASSIGN_MASK_INTX	(1 << 2)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 823544c..8e6f2b1 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2945,6 +2945,23 @@  static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
 	return kvm_vm_ioctl_check_extension(kvm, arg);
 }
 
+#ifdef KVM_DIRTY_LOG_PAGE_OFFSET
+static int kvm_mt_set_dirty_log_size(struct kvm *kvm, u32 size)
+{
+	return -EINVAL;
+}
+
+static int kvm_mt_reset_all_gfns(struct kvm *kvm)
+{
+	return -EINVAL;
+}
+
+static int kvm_mt_get_dirty_count(struct kvm *kvm, u32 *count)
+{
+	return -EINVAL;
+}
+#endif /* KVM_DIRTY_LOG_PAGE_OFFSET*/
+
 static long kvm_vm_ioctl(struct file *filp,
 			   unsigned int ioctl, unsigned long arg)
 {
@@ -3101,9 +3118,37 @@  static long kvm_vm_ioctl(struct file *filp,
 		r = 0;
 		break;
 	}
-	case KVM_CHECK_EXTENSION:
+	case KVM_CHECK_EXTENSION: {
 		r = kvm_vm_ioctl_check_extension_generic(kvm, arg);
 		break;
+	}
+#ifdef KVM_DIRTY_LOG_PAGE_OFFSET
+	case KVM_SET_DIRTY_LOG_SIZE: {
+		u32 size;
+
+		r = -EFAULT;
+		if (copy_from_user(&size, argp, sizeof(u32)))
+			goto out;
+		r = kvm_mt_set_dirty_log_size(kvm, size);
+		break;
+	}
+	case KVM_RESET_DIRTY_PAGES: {
+		r = kvm_mt_reset_all_gfns(kvm);
+		break;
+	}
+	case KVM_GET_DIRTY_COUNT: {
+		u32 count;
+
+		r = kvm_mt_get_dirty_count(kvm, &count);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &count, sizeof(count)))
+			goto out;
+		r = 0;
+		break;
+	}
+#endif /* KVM_DIRTY_LOG_PAGE_OFFSET */
 	default:
 		r = kvm_arch_vm_ioctl(filp, ioctl, arg);
 	}