Commit 4495d6a74575b4ee7e9aabdc66e67b6c9e19a698

Authored by Jan Kiszka
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,6 +58,7 @@ struct KVMState
58 int vmfd; 58 int vmfd;
59 int coalesced_mmio; 59 int coalesced_mmio;
60 int broken_set_mem_region; 60 int broken_set_mem_region;
  61 + int migration_log;
61 #ifdef KVM_CAP_SET_GUEST_DEBUG 62 #ifdef KVM_CAP_SET_GUEST_DEBUG
62 struct kvm_sw_breakpoint_head kvm_sw_breakpoints; 63 struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
63 #endif 64 #endif
@@ -135,7 +136,9 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot) @@ -135,7 +136,9 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
135 mem.memory_size = slot->memory_size; 136 mem.memory_size = slot->memory_size;
136 mem.userspace_addr = (unsigned long)qemu_get_ram_ptr(slot->phys_offset); 137 mem.userspace_addr = (unsigned long)qemu_get_ram_ptr(slot->phys_offset);
137 mem.flags = slot->flags; 138 mem.flags = slot->flags;
138 - 139 + if (s->migration_log) {
  140 + mem.flags |= KVM_MEM_LOG_DIRTY_PAGES;
  141 + }
139 return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); 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,11 +199,12 @@ int kvm_sync_vcpus(void)
196 * dirty pages logging control 199 * dirty pages logging control
197 */ 200 */
198 static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, 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 KVMState *s = kvm_state; 204 KVMState *s = kvm_state;
203 KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size); 205 KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size);
  206 + int old_flags;
  207 +
204 if (mem == NULL) { 208 if (mem == NULL) {
205 fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-" 209 fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-"
206 TARGET_FMT_plx "\n", __func__, phys_addr, 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,13 +212,19 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr,
208 return -EINVAL; 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 mem->flags = flags; 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 return kvm_set_user_memory_region(s, mem); 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,6 +242,28 @@ int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size)
232 KVM_MEM_LOG_DIRTY_PAGES); 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 * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space 268 * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space
237 * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty(). 269 * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty().
@@ -45,6 +45,7 @@ void kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, @@ -45,6 +45,7 @@ void kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
45 45
46 int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size); 46 int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size);
47 int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size); 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 int kvm_has_sync_mmu(void); 50 int kvm_has_sync_mmu(void);
50 51