qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 5/8] kvm: Add missing bits to support live migration


From: Jan Kiszka
Subject: [Qemu-devel] [PATCH 5/8] kvm: Add missing bits to support live migration
Date: Fri, 01 May 2009 23:17:20 +0200
User-agent: StGIT/0.14.2

This patch adds the missing hooks to allow live migration in KVM mode.
It adds proper synchronization before/after saving/restoring the VCPU
states (note: PPC is untested), hooks into
cpu_physical_memory_set_dirty_tracking() to enable dirty memory logging
at KVM level, and synchronizes that drity log into QEMU's view before
running ram_live_save().

Signed-off-by: Jan Kiszka <address@hidden>
---

 exec.c                |    6 ++++++
 target-i386/machine.c |    4 ++++
 target-ppc/machine.c  |    5 +++++
 vl.c                  |    7 ++++++-
 4 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/exec.c b/exec.c
index 90b848f..9718787 100644
--- a/exec.c
+++ b/exec.c
@@ -516,6 +516,8 @@ static void cpu_common_save(QEMUFile *f, void *opaque)
 {
     CPUState *env = opaque;
 
+    cpu_synchronize_state(env, 0);
+
     qemu_put_be32s(f, &env->halted);
     qemu_put_be32s(f, &env->interrupt_request);
 }
@@ -533,6 +535,7 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int 
version_id)
        version_id is increased. */
     env->interrupt_request &= ~0x01;
     tlb_flush(env, 1);
+    cpu_synchronize_state(env, 1);
 
     return 0;
 }
@@ -1923,6 +1926,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, 
ram_addr_t end,
 int cpu_physical_memory_set_dirty_tracking(int enable)
 {
     in_migration = enable;
+    if (kvm_enabled()) {
+        return kvm_set_migration_log(enable);
+    }
     return 0;
 }
 
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 1b0d36d..4fc7335 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -4,6 +4,7 @@
 #include "hw/isa.h"
 
 #include "exec-all.h"
+#include "kvm.h"
 
 void register_machines(void)
 {
@@ -38,6 +39,8 @@ void cpu_save(QEMUFile *f, void *opaque)
     int32_t a20_mask;
     int i;
 
+    cpu_synchronize_state(env, 0);
+
     for(i = 0; i < CPU_NB_REGS; i++)
         qemu_put_betls(f, &env->regs[i]);
     qemu_put_betls(f, &env->eip);
@@ -330,5 +333,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     /* XXX: compute redundant hflags bits */
     env->hflags = hflags;
     tlb_flush(env, 1);
+    cpu_synchronize_state(env, 1);
     return 0;
 }
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 8b82005..ac8702f 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -1,5 +1,6 @@
 #include "hw/hw.h"
 #include "hw/boards.h"
+#include "kvm.h"
 
 void register_machines(void)
 {
@@ -17,6 +18,8 @@ void cpu_save(QEMUFile *f, void *opaque)
     CPUState *env = (CPUState *)opaque;
     unsigned int i, j;
 
+    cpu_synchronize_state(env, 0);
+
     for (i = 0; i < 32; i++)
         qemu_put_betls(f, &env->gpr[i]);
 #if !defined(TARGET_PPC64)
@@ -185,5 +188,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_sbe32s(f, &env->mmu_idx);
     qemu_get_sbe32s(f, &env->power_mode);
 
+    cpu_synchronize_state(env, 1);
+
     return 0;
 }
diff --git a/vl.c b/vl.c
index 867111c..065cffd 100644
--- a/vl.c
+++ b/vl.c
@@ -3248,13 +3248,18 @@ static int ram_save_live(QEMUFile *f, int stage, void 
*opaque)
 {
     ram_addr_t addr;
 
+    if (cpu_physical_sync_dirty_bitmap(0, last_ram_offset) != 0) {
+        qemu_file_set_error(f);
+        return 0;
+    }
+
     if (stage == 1) {
         /* Make sure all dirty bits are set */
         for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
             if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
                 cpu_physical_memory_set_dirty(addr);
         }
-        
+
         /* Enable dirty memory tracking */
         cpu_physical_memory_set_dirty_tracking(1);
 






reply via email to

[Prev in Thread] Current Thread [Next in Thread]