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 | ... | ... |