Commit b0a46a333acfd78da56cf6aebb95f4a5dfb3a4f2
Committed by
Anthony Liguori
1 parent
151f7749
kvm: Add missing bits to support live migration
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 <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
4 changed files
with
21 additions
and
1 deletions
exec.c
| @@ -516,6 +516,8 @@ static void cpu_common_save(QEMUFile *f, void *opaque) | @@ -516,6 +516,8 @@ static void cpu_common_save(QEMUFile *f, void *opaque) | ||
| 516 | { | 516 | { |
| 517 | CPUState *env = opaque; | 517 | CPUState *env = opaque; |
| 518 | 518 | ||
| 519 | + cpu_synchronize_state(env, 0); | ||
| 520 | + | ||
| 519 | qemu_put_be32s(f, &env->halted); | 521 | qemu_put_be32s(f, &env->halted); |
| 520 | qemu_put_be32s(f, &env->interrupt_request); | 522 | qemu_put_be32s(f, &env->interrupt_request); |
| 521 | } | 523 | } |
| @@ -533,6 +535,7 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id) | @@ -533,6 +535,7 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id) | ||
| 533 | version_id is increased. */ | 535 | version_id is increased. */ |
| 534 | env->interrupt_request &= ~0x01; | 536 | env->interrupt_request &= ~0x01; |
| 535 | tlb_flush(env, 1); | 537 | tlb_flush(env, 1); |
| 538 | + cpu_synchronize_state(env, 1); | ||
| 536 | 539 | ||
| 537 | return 0; | 540 | return 0; |
| 538 | } | 541 | } |
| @@ -1923,6 +1926,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, | @@ -1923,6 +1926,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, | ||
| 1923 | int cpu_physical_memory_set_dirty_tracking(int enable) | 1926 | int cpu_physical_memory_set_dirty_tracking(int enable) |
| 1924 | { | 1927 | { |
| 1925 | in_migration = enable; | 1928 | in_migration = enable; |
| 1929 | + if (kvm_enabled()) { | ||
| 1930 | + return kvm_set_migration_log(enable); | ||
| 1931 | + } | ||
| 1926 | return 0; | 1932 | return 0; |
| 1927 | } | 1933 | } |
| 1928 | 1934 |
target-i386/machine.c
| @@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
| 4 | #include "hw/isa.h" | 4 | #include "hw/isa.h" |
| 5 | 5 | ||
| 6 | #include "exec-all.h" | 6 | #include "exec-all.h" |
| 7 | +#include "kvm.h" | ||
| 7 | 8 | ||
| 8 | static void cpu_put_seg(QEMUFile *f, SegmentCache *dt) | 9 | static void cpu_put_seg(QEMUFile *f, SegmentCache *dt) |
| 9 | { | 10 | { |
| @@ -29,6 +30,8 @@ void cpu_save(QEMUFile *f, void *opaque) | @@ -29,6 +30,8 @@ void cpu_save(QEMUFile *f, void *opaque) | ||
| 29 | int32_t a20_mask; | 30 | int32_t a20_mask; |
| 30 | int i; | 31 | int i; |
| 31 | 32 | ||
| 33 | + cpu_synchronize_state(env, 0); | ||
| 34 | + | ||
| 32 | for(i = 0; i < CPU_NB_REGS; i++) | 35 | for(i = 0; i < CPU_NB_REGS; i++) |
| 33 | qemu_put_betls(f, &env->regs[i]); | 36 | qemu_put_betls(f, &env->regs[i]); |
| 34 | qemu_put_betls(f, &env->eip); | 37 | qemu_put_betls(f, &env->eip); |
| @@ -321,5 +324,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | @@ -321,5 +324,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | ||
| 321 | /* XXX: compute redundant hflags bits */ | 324 | /* XXX: compute redundant hflags bits */ |
| 322 | env->hflags = hflags; | 325 | env->hflags = hflags; |
| 323 | tlb_flush(env, 1); | 326 | tlb_flush(env, 1); |
| 327 | + cpu_synchronize_state(env, 1); | ||
| 324 | return 0; | 328 | return 0; |
| 325 | } | 329 | } |
target-ppc/machine.c
| 1 | #include "hw/hw.h" | 1 | #include "hw/hw.h" |
| 2 | #include "hw/boards.h" | 2 | #include "hw/boards.h" |
| 3 | +#include "kvm.h" | ||
| 3 | 4 | ||
| 4 | void cpu_save(QEMUFile *f, void *opaque) | 5 | void cpu_save(QEMUFile *f, void *opaque) |
| 5 | { | 6 | { |
| 6 | CPUState *env = (CPUState *)opaque; | 7 | CPUState *env = (CPUState *)opaque; |
| 7 | unsigned int i, j; | 8 | unsigned int i, j; |
| 8 | 9 | ||
| 10 | + cpu_synchronize_state(env, 0); | ||
| 11 | + | ||
| 9 | for (i = 0; i < 32; i++) | 12 | for (i = 0; i < 32; i++) |
| 10 | qemu_put_betls(f, &env->gpr[i]); | 13 | qemu_put_betls(f, &env->gpr[i]); |
| 11 | #if !defined(TARGET_PPC64) | 14 | #if !defined(TARGET_PPC64) |
| @@ -174,5 +177,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | @@ -174,5 +177,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | ||
| 174 | qemu_get_sbe32s(f, &env->mmu_idx); | 177 | qemu_get_sbe32s(f, &env->mmu_idx); |
| 175 | qemu_get_sbe32s(f, &env->power_mode); | 178 | qemu_get_sbe32s(f, &env->power_mode); |
| 176 | 179 | ||
| 180 | + cpu_synchronize_state(env, 1); | ||
| 181 | + | ||
| 177 | return 0; | 182 | return 0; |
| 178 | } | 183 | } |
vl.c
| @@ -3232,13 +3232,18 @@ static int ram_save_live(QEMUFile *f, int stage, void *opaque) | @@ -3232,13 +3232,18 @@ static int ram_save_live(QEMUFile *f, int stage, void *opaque) | ||
| 3232 | { | 3232 | { |
| 3233 | ram_addr_t addr; | 3233 | ram_addr_t addr; |
| 3234 | 3234 | ||
| 3235 | + if (cpu_physical_sync_dirty_bitmap(0, last_ram_offset) != 0) { | ||
| 3236 | + qemu_file_set_error(f); | ||
| 3237 | + return 0; | ||
| 3238 | + } | ||
| 3239 | + | ||
| 3235 | if (stage == 1) { | 3240 | if (stage == 1) { |
| 3236 | /* Make sure all dirty bits are set */ | 3241 | /* Make sure all dirty bits are set */ |
| 3237 | for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) { | 3242 | for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) { |
| 3238 | if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) | 3243 | if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) |
| 3239 | cpu_physical_memory_set_dirty(addr); | 3244 | cpu_physical_memory_set_dirty(addr); |
| 3240 | } | 3245 | } |
| 3241 | - | 3246 | + |
| 3242 | /* Enable dirty memory tracking */ | 3247 | /* Enable dirty memory tracking */ |
| 3243 | cpu_physical_memory_set_dirty_tracking(1); | 3248 | cpu_physical_memory_set_dirty_tracking(1); |
| 3244 | 3249 |