diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2009-05-01 20:52:46 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-05-22 10:50:33 -0500 |
commit | 4495d6a74575b4ee7e9aabdc66e67b6c9e19a698 (patch) | |
tree | c897a729c9dd8a6ee88e94f505bcf1d3853b3055 /kvm-all.c | |
parent | e69917e29acc6a21a15c5c6b5569333ddf384a38 (diff) |
kvm: Introduce kvm_set_migration_log
Introduce a global dirty logging flag that enforces logging for all
slots. This can be used by the live migration code to enable/disable
global logging withouth destroying the per-slot setting.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'kvm-all.c')
-rw-r--r-- | kvm-all.c | 46 |
1 files changed, 39 insertions, 7 deletions
@@ -58,6 +58,7 @@ struct KVMState int vmfd; int coalesced_mmio; int broken_set_mem_region; + int migration_log; #ifdef KVM_CAP_SET_GUEST_DEBUG struct kvm_sw_breakpoint_head kvm_sw_breakpoints; #endif @@ -135,7 +136,9 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot) mem.memory_size = slot->memory_size; mem.userspace_addr = (unsigned long)qemu_get_ram_ptr(slot->phys_offset); mem.flags = slot->flags; - + if (s->migration_log) { + mem.flags |= KVM_MEM_LOG_DIRTY_PAGES; + } return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); } @@ -196,11 +199,12 @@ int kvm_sync_vcpus(void) * dirty pages logging control */ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, - ram_addr_t size, unsigned flags, - unsigned mask) + ram_addr_t size, int flags, int mask) { KVMState *s = kvm_state; KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size); + int old_flags; + if (mem == NULL) { fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-" TARGET_FMT_plx "\n", __func__, phys_addr, @@ -208,13 +212,19 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, return -EINVAL; } - flags = (mem->flags & ~mask) | flags; - /* Nothing changed, no need to issue ioctl */ - if (flags == mem->flags) - return 0; + old_flags = mem->flags; + flags = (mem->flags & ~mask) | flags; mem->flags = flags; + /* If nothing changed effectively, no need to issue ioctl */ + if (s->migration_log) { + flags |= KVM_MEM_LOG_DIRTY_PAGES; + } + if (flags == old_flags) { + return 0; + } + return kvm_set_user_memory_region(s, mem); } @@ -232,6 +242,28 @@ int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) KVM_MEM_LOG_DIRTY_PAGES); } +int kvm_set_migration_log(int enable) +{ + KVMState *s = kvm_state; + KVMSlot *mem; + int i, err; + + s->migration_log = enable; + + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { + mem = &s->slots[i]; + + if (!!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES) == enable) { + continue; + } + err = kvm_set_user_memory_region(s, mem); + if (err) { + return err; + } + } + return 0; +} + /** * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty(). |