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 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().
... ...
... ... @@ -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  
... ...