diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2015-05-17 05:41:37 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-05-26 06:39:53 -0400 |
| commit | a47d2b07ea755b1761a93df720d725f464876e72 (patch) | |
| tree | e8fd4976c2af4134d3487a5720c52116c832aa0a /virt | |
| parent | a9b4fb7e79e7624c97c55e9c7562e3fe866ce70f (diff) | |
KVM: introduce kvm_alloc/free_memslots
kvm_alloc_memslots is extracted out of previously scattered code
that was in kvm_init_memslots_id and kvm_create_vm.
kvm_free_memslot and kvm_free_memslots are new names of
kvm_free_physmem and kvm_free_physmem_slot, but they also take
an explicit pointer to struct kvm_memslots.
This will simplify the transition to multiple address spaces,
each represented by one pointer to struct kvm_memslots.
Reviewed-by: Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>
Reviewed-by: Radim Krcmar <rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/kvm_main.c | 104 |
1 files changed, 55 insertions, 49 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index bd3c08a7c6c2..e299763ef744 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -440,13 +440,60 @@ static int kvm_init_mmu_notifier(struct kvm *kvm) | |||
| 440 | 440 | ||
| 441 | #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ | 441 | #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ |
| 442 | 442 | ||
| 443 | static void kvm_init_memslots_id(struct kvm *kvm) | 443 | static struct kvm_memslots *kvm_alloc_memslots(void) |
| 444 | { | 444 | { |
| 445 | int i; | 445 | int i; |
| 446 | struct kvm_memslots *slots = kvm->memslots; | 446 | struct kvm_memslots *slots; |
| 447 | 447 | ||
| 448 | slots = kvm_kvzalloc(sizeof(struct kvm_memslots)); | ||
| 449 | if (!slots) | ||
| 450 | return NULL; | ||
| 451 | |||
| 452 | /* | ||
| 453 | * Init kvm generation close to the maximum to easily test the | ||
| 454 | * code of handling generation number wrap-around. | ||
| 455 | */ | ||
| 456 | slots->generation = -150; | ||
| 448 | for (i = 0; i < KVM_MEM_SLOTS_NUM; i++) | 457 | for (i = 0; i < KVM_MEM_SLOTS_NUM; i++) |
| 449 | slots->id_to_index[i] = slots->memslots[i].id = i; | 458 | slots->id_to_index[i] = slots->memslots[i].id = i; |
| 459 | |||
| 460 | return slots; | ||
| 461 | } | ||
| 462 | |||
| 463 | static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot) | ||
| 464 | { | ||
| 465 | if (!memslot->dirty_bitmap) | ||
| 466 | return; | ||
| 467 | |||
| 468 | kvfree(memslot->dirty_bitmap); | ||
| 469 | memslot->dirty_bitmap = NULL; | ||
| 470 | } | ||
| 471 | |||
| 472 | /* | ||
| 473 | * Free any memory in @free but not in @dont. | ||
| 474 | */ | ||
| 475 | static void kvm_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | ||
| 476 | struct kvm_memory_slot *dont) | ||
| 477 | { | ||
| 478 | if (!dont || free->dirty_bitmap != dont->dirty_bitmap) | ||
| 479 | kvm_destroy_dirty_bitmap(free); | ||
| 480 | |||
| 481 | kvm_arch_free_memslot(kvm, free, dont); | ||
| 482 | |||
| 483 | free->npages = 0; | ||
| 484 | } | ||
| 485 | |||
| 486 | static void kvm_free_memslots(struct kvm *kvm, struct kvm_memslots *slots) | ||
| 487 | { | ||
| 488 | struct kvm_memory_slot *memslot; | ||
| 489 | |||
| 490 | if (!slots) | ||
| 491 | return; | ||
| 492 | |||
| 493 | kvm_for_each_memslot(memslot, slots) | ||
| 494 | kvm_free_memslot(kvm, memslot, NULL); | ||
| 495 | |||
| 496 | kvfree(slots); | ||
| 450 | } | 497 | } |
| 451 | 498 | ||
| 452 | static struct kvm *kvm_create_vm(unsigned long type) | 499 | static struct kvm *kvm_create_vm(unsigned long type) |
| @@ -472,17 +519,10 @@ static struct kvm *kvm_create_vm(unsigned long type) | |||
| 472 | BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX); | 519 | BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX); |
| 473 | 520 | ||
| 474 | r = -ENOMEM; | 521 | r = -ENOMEM; |
| 475 | kvm->memslots = kvm_kvzalloc(sizeof(struct kvm_memslots)); | 522 | kvm->memslots = kvm_alloc_memslots(); |
| 476 | if (!kvm->memslots) | 523 | if (!kvm->memslots) |
| 477 | goto out_err_no_srcu; | 524 | goto out_err_no_srcu; |
| 478 | 525 | ||
| 479 | /* | ||
| 480 | * Init kvm generation close to the maximum to easily test the | ||
| 481 | * code of handling generation number wrap-around. | ||
| 482 | */ | ||
| 483 | kvm->memslots->generation = -150; | ||
| 484 | |||
| 485 | kvm_init_memslots_id(kvm); | ||
| 486 | if (init_srcu_struct(&kvm->srcu)) | 526 | if (init_srcu_struct(&kvm->srcu)) |
| 487 | goto out_err_no_srcu; | 527 | goto out_err_no_srcu; |
| 488 | if (init_srcu_struct(&kvm->irq_srcu)) | 528 | if (init_srcu_struct(&kvm->irq_srcu)) |
| @@ -523,7 +563,7 @@ out_err_no_srcu: | |||
| 523 | out_err_no_disable: | 563 | out_err_no_disable: |
| 524 | for (i = 0; i < KVM_NR_BUSES; i++) | 564 | for (i = 0; i < KVM_NR_BUSES; i++) |
| 525 | kfree(kvm->buses[i]); | 565 | kfree(kvm->buses[i]); |
| 526 | kvfree(kvm->memslots); | 566 | kvm_free_memslots(kvm, kvm->memslots); |
| 527 | kvm_arch_free_vm(kvm); | 567 | kvm_arch_free_vm(kvm); |
| 528 | return ERR_PTR(r); | 568 | return ERR_PTR(r); |
| 529 | } | 569 | } |
| @@ -540,40 +580,6 @@ void *kvm_kvzalloc(unsigned long size) | |||
| 540 | return kzalloc(size, GFP_KERNEL); | 580 | return kzalloc(size, GFP_KERNEL); |
| 541 | } | 581 | } |
| 542 | 582 | ||
| 543 | static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot) | ||
| 544 | { | ||
| 545 | if (!memslot->dirty_bitmap) | ||
| 546 | return; | ||
| 547 | |||
| 548 | kvfree(memslot->dirty_bitmap); | ||
| 549 | memslot->dirty_bitmap = NULL; | ||
| 550 | } | ||
| 551 | |||
| 552 | /* | ||
| 553 | * Free any memory in @free but not in @dont. | ||
| 554 | */ | ||
| 555 | static void kvm_free_physmem_slot(struct kvm *kvm, struct kvm_memory_slot *free, | ||
| 556 | struct kvm_memory_slot *dont) | ||
| 557 | { | ||
| 558 | if (!dont || free->dirty_bitmap != dont->dirty_bitmap) | ||
| 559 | kvm_destroy_dirty_bitmap(free); | ||
| 560 | |||
| 561 | kvm_arch_free_memslot(kvm, free, dont); | ||
| 562 | |||
| 563 | free->npages = 0; | ||
| 564 | } | ||
| 565 | |||
| 566 | static void kvm_free_physmem(struct kvm *kvm) | ||
| 567 | { | ||
| 568 | struct kvm_memslots *slots = kvm->memslots; | ||
| 569 | struct kvm_memory_slot *memslot; | ||
| 570 | |||
| 571 | kvm_for_each_memslot(memslot, slots) | ||
| 572 | kvm_free_physmem_slot(kvm, memslot, NULL); | ||
| 573 | |||
| 574 | kvfree(kvm->memslots); | ||
| 575 | } | ||
| 576 | |||
| 577 | static void kvm_destroy_devices(struct kvm *kvm) | 583 | static void kvm_destroy_devices(struct kvm *kvm) |
| 578 | { | 584 | { |
| 579 | struct list_head *node, *tmp; | 585 | struct list_head *node, *tmp; |
| @@ -607,7 +613,7 @@ static void kvm_destroy_vm(struct kvm *kvm) | |||
| 607 | #endif | 613 | #endif |
| 608 | kvm_arch_destroy_vm(kvm); | 614 | kvm_arch_destroy_vm(kvm); |
| 609 | kvm_destroy_devices(kvm); | 615 | kvm_destroy_devices(kvm); |
| 610 | kvm_free_physmem(kvm); | 616 | kvm_free_memslots(kvm, kvm->memslots); |
| 611 | cleanup_srcu_struct(&kvm->irq_srcu); | 617 | cleanup_srcu_struct(&kvm->irq_srcu); |
| 612 | cleanup_srcu_struct(&kvm->srcu); | 618 | cleanup_srcu_struct(&kvm->srcu); |
| 613 | kvm_arch_free_vm(kvm); | 619 | kvm_arch_free_vm(kvm); |
| @@ -898,7 +904,7 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
| 898 | if (r) | 904 | if (r) |
| 899 | goto out_slots; | 905 | goto out_slots; |
| 900 | 906 | ||
| 901 | /* actual memory is freed via old in kvm_free_physmem_slot below */ | 907 | /* actual memory is freed via old in kvm_free_memslot below */ |
| 902 | if (change == KVM_MR_DELETE) { | 908 | if (change == KVM_MR_DELETE) { |
| 903 | new.dirty_bitmap = NULL; | 909 | new.dirty_bitmap = NULL; |
| 904 | memset(&new.arch, 0, sizeof(new.arch)); | 910 | memset(&new.arch, 0, sizeof(new.arch)); |
| @@ -909,7 +915,7 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
| 909 | 915 | ||
| 910 | kvm_arch_commit_memory_region(kvm, mem, &old, change); | 916 | kvm_arch_commit_memory_region(kvm, mem, &old, change); |
| 911 | 917 | ||
| 912 | kvm_free_physmem_slot(kvm, &old, &new); | 918 | kvm_free_memslot(kvm, &old, &new); |
| 913 | kvfree(old_memslots); | 919 | kvfree(old_memslots); |
| 914 | 920 | ||
| 915 | /* | 921 | /* |
| @@ -931,7 +937,7 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
| 931 | out_slots: | 937 | out_slots: |
| 932 | kvfree(slots); | 938 | kvfree(slots); |
| 933 | out_free: | 939 | out_free: |
| 934 | kvm_free_physmem_slot(kvm, &new, &old); | 940 | kvm_free_memslot(kvm, &new, &old); |
| 935 | out: | 941 | out: |
| 936 | return r; | 942 | return r; |
| 937 | } | 943 | } |
