Commit 4495d6a74575b4ee7e9aabdc66e67b6c9e19a698
Committed by
Anthony Liguori
1 parent
e69917e2
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>
Showing
2 changed files
with
40 additions
and
7 deletions
kvm-all.c
| ... | ... | @@ -58,6 +58,7 @@ struct KVMState |
| 58 | 58 | int vmfd; |
| 59 | 59 | int coalesced_mmio; |
| 60 | 60 | int broken_set_mem_region; |
| 61 | + int migration_log; | |
| 61 | 62 | #ifdef KVM_CAP_SET_GUEST_DEBUG |
| 62 | 63 | struct kvm_sw_breakpoint_head kvm_sw_breakpoints; |
| 63 | 64 | #endif |
| ... | ... | @@ -135,7 +136,9 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot) |
| 135 | 136 | mem.memory_size = slot->memory_size; |
| 136 | 137 | mem.userspace_addr = (unsigned long)qemu_get_ram_ptr(slot->phys_offset); |
| 137 | 138 | mem.flags = slot->flags; |
| 138 | - | |
| 139 | + if (s->migration_log) { | |
| 140 | + mem.flags |= KVM_MEM_LOG_DIRTY_PAGES; | |
| 141 | + } | |
| 139 | 142 | return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); |
| 140 | 143 | } |
| 141 | 144 | |
| ... | ... | @@ -196,11 +199,12 @@ int kvm_sync_vcpus(void) |
| 196 | 199 | * dirty pages logging control |
| 197 | 200 | */ |
| 198 | 201 | static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, |
| 199 | - ram_addr_t size, unsigned flags, | |
| 200 | - unsigned mask) | |
| 202 | + ram_addr_t size, int flags, int mask) | |
| 201 | 203 | { |
| 202 | 204 | KVMState *s = kvm_state; |
| 203 | 205 | KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size); |
| 206 | + int old_flags; | |
| 207 | + | |
| 204 | 208 | if (mem == NULL) { |
| 205 | 209 | fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-" |
| 206 | 210 | TARGET_FMT_plx "\n", __func__, phys_addr, |
| ... | ... | @@ -208,13 +212,19 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, |
| 208 | 212 | return -EINVAL; |
| 209 | 213 | } |
| 210 | 214 | |
| 211 | - flags = (mem->flags & ~mask) | flags; | |
| 212 | - /* Nothing changed, no need to issue ioctl */ | |
| 213 | - if (flags == mem->flags) | |
| 214 | - return 0; | |
| 215 | + old_flags = mem->flags; | |
| 215 | 216 | |
| 217 | + flags = (mem->flags & ~mask) | flags; | |
| 216 | 218 | mem->flags = flags; |
| 217 | 219 | |
| 220 | + /* If nothing changed effectively, no need to issue ioctl */ | |
| 221 | + if (s->migration_log) { | |
| 222 | + flags |= KVM_MEM_LOG_DIRTY_PAGES; | |
| 223 | + } | |
| 224 | + if (flags == old_flags) { | |
| 225 | + return 0; | |
| 226 | + } | |
| 227 | + | |
| 218 | 228 | return kvm_set_user_memory_region(s, mem); |
| 219 | 229 | } |
| 220 | 230 | |
| ... | ... | @@ -232,6 +242,28 @@ int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) |
| 232 | 242 | KVM_MEM_LOG_DIRTY_PAGES); |
| 233 | 243 | } |
| 234 | 244 | |
| 245 | +int kvm_set_migration_log(int enable) | |
| 246 | +{ | |
| 247 | + KVMState *s = kvm_state; | |
| 248 | + KVMSlot *mem; | |
| 249 | + int i, err; | |
| 250 | + | |
| 251 | + s->migration_log = enable; | |
| 252 | + | |
| 253 | + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { | |
| 254 | + mem = &s->slots[i]; | |
| 255 | + | |
| 256 | + if (!!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES) == enable) { | |
| 257 | + continue; | |
| 258 | + } | |
| 259 | + err = kvm_set_user_memory_region(s, mem); | |
| 260 | + if (err) { | |
| 261 | + return err; | |
| 262 | + } | |
| 263 | + } | |
| 264 | + return 0; | |
| 265 | +} | |
| 266 | + | |
| 235 | 267 | /** |
| 236 | 268 | * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space |
| 237 | 269 | * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty(). | ... | ... |
kvm.h
| ... | ... | @@ -45,6 +45,7 @@ void kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, |
| 45 | 45 | |
| 46 | 46 | int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size); |
| 47 | 47 | int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size); |
| 48 | +int kvm_set_migration_log(int enable); | |
| 48 | 49 | |
| 49 | 50 | int kvm_has_sync_mmu(void); |
| 50 | 51 | ... | ... |