Commit a47d2b07 authored by Paolo Bonzini's avatar Paolo Bonzini

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: default avatarTakuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>
Reviewed-by: default avatarRadim Krcmar <rkrcmar@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a9b4fb7e
...@@ -440,13 +440,60 @@ static int kvm_init_mmu_notifier(struct kvm *kvm) ...@@ -440,13 +440,60 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
#endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */
static void kvm_init_memslots_id(struct kvm *kvm) static struct kvm_memslots *kvm_alloc_memslots(void)
{ {
int i; int i;
struct kvm_memslots *slots = kvm->memslots; struct kvm_memslots *slots;
slots = kvm_kvzalloc(sizeof(struct kvm_memslots));
if (!slots)
return NULL;
/*
* Init kvm generation close to the maximum to easily test the
* code of handling generation number wrap-around.
*/
slots->generation = -150;
for (i = 0; i < KVM_MEM_SLOTS_NUM; i++) for (i = 0; i < KVM_MEM_SLOTS_NUM; i++)
slots->id_to_index[i] = slots->memslots[i].id = i; slots->id_to_index[i] = slots->memslots[i].id = i;
return slots;
}
static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
{
if (!memslot->dirty_bitmap)
return;
kvfree(memslot->dirty_bitmap);
memslot->dirty_bitmap = NULL;
}
/*
* Free any memory in @free but not in @dont.
*/
static void kvm_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
struct kvm_memory_slot *dont)
{
if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
kvm_destroy_dirty_bitmap(free);
kvm_arch_free_memslot(kvm, free, dont);
free->npages = 0;
}
static void kvm_free_memslots(struct kvm *kvm, struct kvm_memslots *slots)
{
struct kvm_memory_slot *memslot;
if (!slots)
return;
kvm_for_each_memslot(memslot, slots)
kvm_free_memslot(kvm, memslot, NULL);
kvfree(slots);
} }
static struct kvm *kvm_create_vm(unsigned long type) static struct kvm *kvm_create_vm(unsigned long type)
...@@ -472,17 +519,10 @@ static struct kvm *kvm_create_vm(unsigned long type) ...@@ -472,17 +519,10 @@ static struct kvm *kvm_create_vm(unsigned long type)
BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX); BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
r = -ENOMEM; r = -ENOMEM;
kvm->memslots = kvm_kvzalloc(sizeof(struct kvm_memslots)); kvm->memslots = kvm_alloc_memslots();
if (!kvm->memslots) if (!kvm->memslots)
goto out_err_no_srcu; goto out_err_no_srcu;
/*
* Init kvm generation close to the maximum to easily test the
* code of handling generation number wrap-around.
*/
kvm->memslots->generation = -150;
kvm_init_memslots_id(kvm);
if (init_srcu_struct(&kvm->srcu)) if (init_srcu_struct(&kvm->srcu))
goto out_err_no_srcu; goto out_err_no_srcu;
if (init_srcu_struct(&kvm->irq_srcu)) if (init_srcu_struct(&kvm->irq_srcu))
...@@ -523,7 +563,7 @@ static struct kvm *kvm_create_vm(unsigned long type) ...@@ -523,7 +563,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
out_err_no_disable: out_err_no_disable:
for (i = 0; i < KVM_NR_BUSES; i++) for (i = 0; i < KVM_NR_BUSES; i++)
kfree(kvm->buses[i]); kfree(kvm->buses[i]);
kvfree(kvm->memslots); kvm_free_memslots(kvm, kvm->memslots);
kvm_arch_free_vm(kvm); kvm_arch_free_vm(kvm);
return ERR_PTR(r); return ERR_PTR(r);
} }
...@@ -540,40 +580,6 @@ void *kvm_kvzalloc(unsigned long size) ...@@ -540,40 +580,6 @@ void *kvm_kvzalloc(unsigned long size)
return kzalloc(size, GFP_KERNEL); return kzalloc(size, GFP_KERNEL);
} }
static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
{
if (!memslot->dirty_bitmap)
return;
kvfree(memslot->dirty_bitmap);
memslot->dirty_bitmap = NULL;
}
/*
* Free any memory in @free but not in @dont.
*/
static void kvm_free_physmem_slot(struct kvm *kvm, struct kvm_memory_slot *free,
struct kvm_memory_slot *dont)
{
if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
kvm_destroy_dirty_bitmap(free);
kvm_arch_free_memslot(kvm, free, dont);
free->npages = 0;
}
static void kvm_free_physmem(struct kvm *kvm)
{
struct kvm_memslots *slots = kvm->memslots;
struct kvm_memory_slot *memslot;
kvm_for_each_memslot(memslot, slots)
kvm_free_physmem_slot(kvm, memslot, NULL);
kvfree(kvm->memslots);
}
static void kvm_destroy_devices(struct kvm *kvm) static void kvm_destroy_devices(struct kvm *kvm)
{ {
struct list_head *node, *tmp; struct list_head *node, *tmp;
...@@ -607,7 +613,7 @@ static void kvm_destroy_vm(struct kvm *kvm) ...@@ -607,7 +613,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
#endif #endif
kvm_arch_destroy_vm(kvm); kvm_arch_destroy_vm(kvm);
kvm_destroy_devices(kvm); kvm_destroy_devices(kvm);
kvm_free_physmem(kvm); kvm_free_memslots(kvm, kvm->memslots);
cleanup_srcu_struct(&kvm->irq_srcu); cleanup_srcu_struct(&kvm->irq_srcu);
cleanup_srcu_struct(&kvm->srcu); cleanup_srcu_struct(&kvm->srcu);
kvm_arch_free_vm(kvm); kvm_arch_free_vm(kvm);
...@@ -898,7 +904,7 @@ int __kvm_set_memory_region(struct kvm *kvm, ...@@ -898,7 +904,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
if (r) if (r)
goto out_slots; goto out_slots;
/* actual memory is freed via old in kvm_free_physmem_slot below */ /* actual memory is freed via old in kvm_free_memslot below */
if (change == KVM_MR_DELETE) { if (change == KVM_MR_DELETE) {
new.dirty_bitmap = NULL; new.dirty_bitmap = NULL;
memset(&new.arch, 0, sizeof(new.arch)); memset(&new.arch, 0, sizeof(new.arch));
...@@ -909,7 +915,7 @@ int __kvm_set_memory_region(struct kvm *kvm, ...@@ -909,7 +915,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
kvm_arch_commit_memory_region(kvm, mem, &old, change); kvm_arch_commit_memory_region(kvm, mem, &old, change);
kvm_free_physmem_slot(kvm, &old, &new); kvm_free_memslot(kvm, &old, &new);
kvfree(old_memslots); kvfree(old_memslots);
/* /*
...@@ -931,7 +937,7 @@ int __kvm_set_memory_region(struct kvm *kvm, ...@@ -931,7 +937,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
out_slots: out_slots:
kvfree(slots); kvfree(slots);
out_free: out_free:
kvm_free_physmem_slot(kvm, &new, &old); kvm_free_memslot(kvm, &new, &old);
out: out:
return r; return r;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment