diff options
| author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2010-10-27 05:22:19 -0400 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2011-01-12 04:28:45 -0500 |
| commit | a36a57b1a19bce17b67f5c6f43460baf664ae5fa (patch) | |
| tree | 3cc8133240d81c3b1871db29d1958896a4fd8742 /virt | |
| parent | 64be5007066173d11a4635eedd57d41a3b3a7027 (diff) | |
KVM: introduce wrapper functions for creating/destroying dirty bitmaps
This makes it easy to change the way of allocating/freeing dirty bitmaps.
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/kvm_main.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 880370caf9ed..0021c2862140 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -444,6 +444,15 @@ out_err_nodisable: | |||
| 444 | return ERR_PTR(r); | 444 | return ERR_PTR(r); |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot) | ||
| 448 | { | ||
| 449 | if (!memslot->dirty_bitmap) | ||
| 450 | return; | ||
| 451 | |||
| 452 | vfree(memslot->dirty_bitmap); | ||
| 453 | memslot->dirty_bitmap = NULL; | ||
| 454 | } | ||
| 455 | |||
| 447 | /* | 456 | /* |
| 448 | * Free any memory in @free but not in @dont. | 457 | * Free any memory in @free but not in @dont. |
| 449 | */ | 458 | */ |
| @@ -456,7 +465,7 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free, | |||
| 456 | vfree(free->rmap); | 465 | vfree(free->rmap); |
| 457 | 466 | ||
| 458 | if (!dont || free->dirty_bitmap != dont->dirty_bitmap) | 467 | if (!dont || free->dirty_bitmap != dont->dirty_bitmap) |
| 459 | vfree(free->dirty_bitmap); | 468 | kvm_destroy_dirty_bitmap(free); |
| 460 | 469 | ||
| 461 | 470 | ||
| 462 | for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { | 471 | for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { |
| @@ -467,7 +476,6 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free, | |||
| 467 | } | 476 | } |
| 468 | 477 | ||
| 469 | free->npages = 0; | 478 | free->npages = 0; |
| 470 | free->dirty_bitmap = NULL; | ||
| 471 | free->rmap = NULL; | 479 | free->rmap = NULL; |
| 472 | } | 480 | } |
| 473 | 481 | ||
| @@ -529,6 +537,18 @@ static int kvm_vm_release(struct inode *inode, struct file *filp) | |||
| 529 | return 0; | 537 | return 0; |
| 530 | } | 538 | } |
| 531 | 539 | ||
| 540 | static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) | ||
| 541 | { | ||
| 542 | unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot); | ||
| 543 | |||
| 544 | memslot->dirty_bitmap = vmalloc(dirty_bytes); | ||
| 545 | if (!memslot->dirty_bitmap) | ||
| 546 | return -ENOMEM; | ||
| 547 | |||
| 548 | memset(memslot->dirty_bitmap, 0, dirty_bytes); | ||
| 549 | return 0; | ||
| 550 | } | ||
| 551 | |||
| 532 | /* | 552 | /* |
| 533 | * Allocate some memory and give it an address in the guest physical address | 553 | * Allocate some memory and give it an address in the guest physical address |
| 534 | * space. | 554 | * space. |
| @@ -663,12 +683,8 @@ skip_lpage: | |||
| 663 | 683 | ||
| 664 | /* Allocate page dirty bitmap if needed */ | 684 | /* Allocate page dirty bitmap if needed */ |
| 665 | if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) { | 685 | if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) { |
| 666 | unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new); | 686 | if (kvm_create_dirty_bitmap(&new) < 0) |
| 667 | |||
| 668 | new.dirty_bitmap = vmalloc(dirty_bytes); | ||
| 669 | if (!new.dirty_bitmap) | ||
| 670 | goto out_free; | 687 | goto out_free; |
| 671 | memset(new.dirty_bitmap, 0, dirty_bytes); | ||
| 672 | /* destroy any largepage mappings for dirty tracking */ | 688 | /* destroy any largepage mappings for dirty tracking */ |
| 673 | if (old.npages) | 689 | if (old.npages) |
| 674 | flush_shadow = 1; | 690 | flush_shadow = 1; |
