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>
This commit is contained in:
parent
e69917e29a
commit
4495d6a745
46
kvm-all.c
46
kvm-all.c
@ -58,6 +58,7 @@ struct KVMState
|
|||||||
int vmfd;
|
int vmfd;
|
||||||
int coalesced_mmio;
|
int coalesced_mmio;
|
||||||
int broken_set_mem_region;
|
int broken_set_mem_region;
|
||||||
|
int migration_log;
|
||||||
#ifdef KVM_CAP_SET_GUEST_DEBUG
|
#ifdef KVM_CAP_SET_GUEST_DEBUG
|
||||||
struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
|
struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
|
||||||
#endif
|
#endif
|
||||||
@ -135,7 +136,9 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
|
|||||||
mem.memory_size = slot->memory_size;
|
mem.memory_size = slot->memory_size;
|
||||||
mem.userspace_addr = (unsigned long)qemu_get_ram_ptr(slot->phys_offset);
|
mem.userspace_addr = (unsigned long)qemu_get_ram_ptr(slot->phys_offset);
|
||||||
mem.flags = slot->flags;
|
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);
|
return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,11 +199,12 @@ int kvm_sync_vcpus(void)
|
|||||||
* dirty pages logging control
|
* dirty pages logging control
|
||||||
*/
|
*/
|
||||||
static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr,
|
static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr,
|
||||||
ram_addr_t size, unsigned flags,
|
ram_addr_t size, int flags, int mask)
|
||||||
unsigned mask)
|
|
||||||
{
|
{
|
||||||
KVMState *s = kvm_state;
|
KVMState *s = kvm_state;
|
||||||
KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size);
|
KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size);
|
||||||
|
int old_flags;
|
||||||
|
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-"
|
fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-"
|
||||||
TARGET_FMT_plx "\n", __func__, phys_addr,
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = (mem->flags & ~mask) | flags;
|
old_flags = mem->flags;
|
||||||
/* Nothing changed, no need to issue ioctl */
|
|
||||||
if (flags == mem->flags)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
flags = (mem->flags & ~mask) | flags;
|
||||||
mem->flags = 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);
|
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);
|
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
|
* kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space
|
||||||
* This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty().
|
* This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty().
|
||||||
|
1
kvm.h
1
kvm.h
@ -45,6 +45,7 @@ void kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
|
|||||||
|
|
||||||
int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size);
|
int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size);
|
||||||
int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size);
|
int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size);
|
||||||
|
int kvm_set_migration_log(int enable);
|
||||||
|
|
||||||
int kvm_has_sync_mmu(void);
|
int kvm_has_sync_mmu(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user