aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/x86.c16
-rw-r--r--include/linux/kvm_host.h1
-rw-r--r--virt/kvm/kvm_main.c11
3 files changed, 15 insertions, 13 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a2a785472431..35f82f2c66f6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3208,18 +3208,15 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
3208 struct kvm_memslots *slots, *old_slots; 3208 struct kvm_memslots *slots, *old_slots;
3209 unsigned long *dirty_bitmap; 3209 unsigned long *dirty_bitmap;
3210 3210
3211 r = -ENOMEM; 3211 dirty_bitmap = memslot->dirty_bitmap_head;
3212 dirty_bitmap = vmalloc(n); 3212 if (memslot->dirty_bitmap == dirty_bitmap)
3213 if (!dirty_bitmap) 3213 dirty_bitmap += n / sizeof(long);
3214 goto out;
3215 memset(dirty_bitmap, 0, n); 3214 memset(dirty_bitmap, 0, n);
3216 3215
3217 r = -ENOMEM; 3216 r = -ENOMEM;
3218 slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL); 3217 slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
3219 if (!slots) { 3218 if (!slots)
3220 vfree(dirty_bitmap);
3221 goto out; 3219 goto out;
3222 }
3223 memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots)); 3220 memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
3224 slots->memslots[log->slot].dirty_bitmap = dirty_bitmap; 3221 slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
3225 slots->generation++; 3222 slots->generation++;
@@ -3235,11 +3232,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
3235 spin_unlock(&kvm->mmu_lock); 3232 spin_unlock(&kvm->mmu_lock);
3236 3233
3237 r = -EFAULT; 3234 r = -EFAULT;
3238 if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) { 3235 if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
3239 vfree(dirty_bitmap);
3240 goto out; 3236 goto out;
3241 }
3242 vfree(dirty_bitmap);
3243 } else { 3237 } else {
3244 r = -EFAULT; 3238 r = -EFAULT;
3245 if (clear_user(log->dirty_bitmap, n)) 3239 if (clear_user(log->dirty_bitmap, n))
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 462b982fedfb..bcf71c7730f0 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -150,6 +150,7 @@ struct kvm_memory_slot {
150 unsigned long flags; 150 unsigned long flags;
151 unsigned long *rmap; 151 unsigned long *rmap;
152 unsigned long *dirty_bitmap; 152 unsigned long *dirty_bitmap;
153 unsigned long *dirty_bitmap_head;
153 struct { 154 struct {
154 unsigned long rmap_pde; 155 unsigned long rmap_pde;
155 int write_count; 156 int write_count;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 0021c2862140..27649fdaa007 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -449,8 +449,9 @@ static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
449 if (!memslot->dirty_bitmap) 449 if (!memslot->dirty_bitmap)
450 return; 450 return;
451 451
452 vfree(memslot->dirty_bitmap); 452 vfree(memslot->dirty_bitmap_head);
453 memslot->dirty_bitmap = NULL; 453 memslot->dirty_bitmap = NULL;
454 memslot->dirty_bitmap_head = NULL;
454} 455}
455 456
456/* 457/*
@@ -537,15 +538,21 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
537 return 0; 538 return 0;
538} 539}
539 540
541/*
542 * Allocation size is twice as large as the actual dirty bitmap size.
543 * This makes it possible to do double buffering: see x86's
544 * kvm_vm_ioctl_get_dirty_log().
545 */
540static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) 546static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
541{ 547{
542 unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot); 548 unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot);
543 549
544 memslot->dirty_bitmap = vmalloc(dirty_bytes); 550 memslot->dirty_bitmap = vmalloc(dirty_bytes);
545 if (!memslot->dirty_bitmap) 551 if (!memslot->dirty_bitmap)
546 return -ENOMEM; 552 return -ENOMEM;
547 553
548 memset(memslot->dirty_bitmap, 0, dirty_bytes); 554 memset(memslot->dirty_bitmap, 0, dirty_bytes);
555 memslot->dirty_bitmap_head = memslot->dirty_bitmap;
549 return 0; 556 return 0;
550} 557}
551 558