Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 84

kvm-83-270.el5_11.src.rpm

From 5ea533dfa9bf8210a6802f42c1eb03f4719a4b00 Mon Sep 17 00:00:00 2001
From: Glauber Costa <glommer@redhat.com>
Date: Tue, 10 Nov 2009 13:52:00 -0200
Subject: [PATCH 2/2] BZ531701: get and set clock upon migration

RH-Author: Glauber Costa <glommer@redhat.com>
Message-id: <1256806337-16149-3-git-send-email-glommer@redhat.com>
Patchwork-id: 3641
O-Subject: [PATCH 2/2] BZ531701: get and set clock upon migration
Bugzilla: 531701
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>

Register a vmstate handler for kvmclock. The goal here is to pass
information about current time to migration, so we avoid going backwards
or jumping too much. We use our plain new ioctls for that.

Signed-off-by: Glauber Costa <glommer@redhat.com>
RH-Bugzilla: BZ531701
RH-Upstream-status: kvm/master
---
 libkvm/libkvm-x86.c |   23 +++++++++++++++++++++++
 libkvm/libkvm.h     |    3 +++
 qemu/qemu-kvm-x86.c |   30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 0 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 libkvm/libkvm-x86.c |   23 +++++++++++++++++++++++
 libkvm/libkvm.h     |    3 +++
 qemu/qemu-kvm-x86.c |   30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c
index dcef548..c10c7e5 100644
--- a/libkvm/libkvm-x86.c
+++ b/libkvm/libkvm-x86.c
@@ -562,3 +562,26 @@ int kvm_disable_tpr_access_reporting(kvm_context_t kvm, int vcpu)
 }
 
 #endif
+
+#ifdef KVM_CAP_ADJUST_CLOCK
+
+int kvm_can_adjust_clock(kvm_context_t kvm)
+{
+	int r;
+	r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_ADJUST_CLOCK);
+	if (r == -1 || r == 0)
+		return 0;
+	return 1;
+}
+
+int kvm_get_clock(kvm_context_t kvm, struct kvm_clock_data *cl)
+{
+	return ioctl(kvm->vm_fd, KVM_GET_CLOCK, cl);
+}
+
+int kvm_set_clock(kvm_context_t kvm, struct kvm_clock_data *cl)
+{
+	return ioctl(kvm->vm_fd, KVM_SET_CLOCK, cl);
+}
+#endif
+
diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
index 94ad31d..be163e8 100644
--- a/libkvm/libkvm.h
+++ b/libkvm/libkvm.h
@@ -861,4 +861,7 @@ int kvm_assign_set_msix_nr(kvm_context_t kvm,
 int kvm_assign_set_msix_entry(kvm_context_t kvm,
                               struct kvm_assigned_msix_entry *entry);
 #endif
+int kvm_get_clock(kvm_context_t kvm, struct kvm_clock_data *cl);
+int kvm_set_clock(kvm_context_t kvm, struct kvm_clock_data *cl);
+int kvm_can_adjust_clock(kvm_context_t kvm);
 #endif
diff --git a/qemu/qemu-kvm-x86.c b/qemu/qemu-kvm-x86.c
index de709ae..b573029 100644
--- a/qemu/qemu-kvm-x86.c
+++ b/qemu/qemu-kvm-x86.c
@@ -40,6 +40,31 @@ int kvm_qemu_destroy_memory_alias(uint64_t phys_start)
 	return kvm_destroy_memory_alias(kvm_context, phys_start);
 }
 
+#ifdef KVM_CAP_ADJUST_CLOCK
+static struct kvm_clock_data kvmclock_data;
+
+static void kvmclock_save(QEMUFile *f, void *opaque)
+{
+    struct kvm_clock_data *cl = opaque;
+
+    kvm_get_clock(kvm_context, cl); 
+
+    qemu_put_be64s(f, (uint64_t *)&cl->clock);
+}
+
+static int kvmclock_load(QEMUFile *f, void *opaque, int version_id)
+{
+    struct kvm_clock_data *cl = opaque;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_be64s(f, (uint64_t *)&cl->clock);
+
+    return kvm_set_clock(kvm_context, cl);
+}
+#endif
+
 int kvm_arch_qemu_create_context(void)
 {
     int i;
@@ -57,6 +82,11 @@ int kvm_arch_qemu_create_context(void)
     for (i = 0; i < kvm_msr_list->nmsrs; ++i)
 	if (kvm_msr_list->indices[i] == MSR_STAR)
 	    kvm_has_msr_star = 1;
+
+#ifdef KVM_CAP_ADJUST_CLOCK
+    if (kvm_can_adjust_clock(kvm_context))
+        register_savevm("kvmclock", 0, 1, kvmclock_save, kvmclock_load, &kvmclock_data);
+#endif
 	return 0;
 }
 
-- 
1.6.3.rc4.29.g8146