aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2010-11-09 11:02:49 -0500
committerAvi Kivity <avi@redhat.com>2011-01-12 04:29:09 -0500
commitd89f5eff70a31237ffa1e21c51d23ca532110aea (patch)
tree13b47648a564d8382e08d7e5937ea30ff0fb838c
parent9d893c6bc177b6ac5a1e937f4fdc359d272d68ff (diff)
KVM: Clean up vm creation and release
IA64 support forces us to abstract the allocation of the kvm structure. But instead of mixing this up with arch-specific initialization and doing the same on destruction, split both steps. This allows to move generic destruction calls into generic code. It also fixes error clean-up on failures of kvm_create_vm for IA64. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/ia64/include/asm/kvm_host.h4
-rw-r--r--arch/ia64/kvm/kvm-ia64.c28
-rw-r--r--arch/powerpc/kvm/powerpc.c20
-rw-r--r--arch/s390/kvm/kvm-s390.c23
-rw-r--r--arch/x86/kvm/x86.c12
-rw-r--r--include/linux/kvm_host.h15
-rw-r--r--virt/kvm/kvm_main.c19
7 files changed, 49 insertions, 72 deletions
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index 2f229e5de498..2689ee54a1c9 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -590,6 +590,10 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu);
590int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); 590int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
591void kvm_sal_emul(struct kvm_vcpu *vcpu); 591void kvm_sal_emul(struct kvm_vcpu *vcpu);
592 592
593#define __KVM_HAVE_ARCH_VM_ALLOC 1
594struct kvm *kvm_arch_alloc_vm(void);
595void kvm_arch_free_vm(struct kvm *kvm);
596
593#endif /* __ASSEMBLY__*/ 597#endif /* __ASSEMBLY__*/
594 598
595#endif 599#endif
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index f56a6316e134..48a48bdc59c3 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -749,7 +749,7 @@ out:
749 return r; 749 return r;
750} 750}
751 751
752static struct kvm *kvm_alloc_kvm(void) 752struct kvm *kvm_arch_alloc_vm(void)
753{ 753{
754 754
755 struct kvm *kvm; 755 struct kvm *kvm;
@@ -760,7 +760,7 @@ static struct kvm *kvm_alloc_kvm(void)
760 vm_base = __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE)); 760 vm_base = __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE));
761 761
762 if (!vm_base) 762 if (!vm_base)
763 return ERR_PTR(-ENOMEM); 763 return NULL;
764 764
765 memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); 765 memset((void *)vm_base, 0, KVM_VM_DATA_SIZE);
766 kvm = (struct kvm *)(vm_base + 766 kvm = (struct kvm *)(vm_base +
@@ -806,10 +806,12 @@ static void kvm_build_io_pmt(struct kvm *kvm)
806#define GUEST_PHYSICAL_RR4 0x2739 806#define GUEST_PHYSICAL_RR4 0x2739
807#define VMM_INIT_RR 0x1660 807#define VMM_INIT_RR 0x1660
808 808
809static void kvm_init_vm(struct kvm *kvm) 809int kvm_arch_init_vm(struct kvm *kvm)
810{ 810{
811 BUG_ON(!kvm); 811 BUG_ON(!kvm);
812 812
813 kvm->arch.is_sn2 = ia64_platform_is("sn2");
814
813 kvm->arch.metaphysical_rr0 = GUEST_PHYSICAL_RR0; 815 kvm->arch.metaphysical_rr0 = GUEST_PHYSICAL_RR0;
814 kvm->arch.metaphysical_rr4 = GUEST_PHYSICAL_RR4; 816 kvm->arch.metaphysical_rr4 = GUEST_PHYSICAL_RR4;
815 kvm->arch.vmm_init_rr = VMM_INIT_RR; 817 kvm->arch.vmm_init_rr = VMM_INIT_RR;
@@ -823,21 +825,8 @@ static void kvm_init_vm(struct kvm *kvm)
823 825
824 /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ 826 /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
825 set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); 827 set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap);
826}
827
828struct kvm *kvm_arch_create_vm(void)
829{
830 struct kvm *kvm = kvm_alloc_kvm();
831
832 if (IS_ERR(kvm))
833 return ERR_PTR(-ENOMEM);
834
835 kvm->arch.is_sn2 = ia64_platform_is("sn2");
836
837 kvm_init_vm(kvm);
838
839 return kvm;
840 828
829 return 0;
841} 830}
842 831
843static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, 832static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm,
@@ -1357,7 +1346,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
1357 return -EINVAL; 1346 return -EINVAL;
1358} 1347}
1359 1348
1360static void free_kvm(struct kvm *kvm) 1349void kvm_arch_free_vm(struct kvm *kvm)
1361{ 1350{
1362 unsigned long vm_base = kvm->arch.vm_base; 1351 unsigned long vm_base = kvm->arch.vm_base;
1363 1352
@@ -1399,9 +1388,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
1399#endif 1388#endif
1400 kfree(kvm->arch.vioapic); 1389 kfree(kvm->arch.vioapic);
1401 kvm_release_vm_pages(kvm); 1390 kvm_release_vm_pages(kvm);
1402 kvm_free_physmem(kvm);
1403 cleanup_srcu_struct(&kvm->srcu);
1404 free_kvm(kvm);
1405} 1391}
1406 1392
1407void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) 1393void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 38f756f25053..99758460efde 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -145,18 +145,12 @@ void kvm_arch_check_processor_compat(void *rtn)
145 *(int *)rtn = kvmppc_core_check_processor_compat(); 145 *(int *)rtn = kvmppc_core_check_processor_compat();
146} 146}
147 147
148struct kvm *kvm_arch_create_vm(void) 148int kvm_arch_init_vm(struct kvm *kvm)
149{ 149{
150 struct kvm *kvm; 150 return 0;
151
152 kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
153 if (!kvm)
154 return ERR_PTR(-ENOMEM);
155
156 return kvm;
157} 151}
158 152
159static void kvmppc_free_vcpus(struct kvm *kvm) 153void kvm_arch_destroy_vm(struct kvm *kvm)
160{ 154{
161 unsigned int i; 155 unsigned int i;
162 struct kvm_vcpu *vcpu; 156 struct kvm_vcpu *vcpu;
@@ -176,14 +170,6 @@ void kvm_arch_sync_events(struct kvm *kvm)
176{ 170{
177} 171}
178 172
179void kvm_arch_destroy_vm(struct kvm *kvm)
180{
181 kvmppc_free_vcpus(kvm);
182 kvm_free_physmem(kvm);
183 cleanup_srcu_struct(&kvm->srcu);
184 kfree(kvm);
185}
186
187int kvm_dev_ioctl_check_extension(long ext) 173int kvm_dev_ioctl_check_extension(long ext)
188{ 174{
189 int r; 175 int r;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 985d825494f1..bade533ba288 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -164,24 +164,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
164 return r; 164 return r;
165} 165}
166 166
167struct kvm *kvm_arch_create_vm(void) 167int kvm_arch_init_vm(struct kvm *kvm)
168{ 168{
169 struct kvm *kvm;
170 int rc; 169 int rc;
171 char debug_name[16]; 170 char debug_name[16];
172 171
173 rc = s390_enable_sie(); 172 rc = s390_enable_sie();
174 if (rc) 173 if (rc)
175 goto out_nokvm; 174 goto out_err;
176
177 rc = -ENOMEM;
178 kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
179 if (!kvm)
180 goto out_nokvm;
181 175
182 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL); 176 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
183 if (!kvm->arch.sca) 177 if (!kvm->arch.sca)
184 goto out_nosca; 178 goto out_err;
185 179
186 sprintf(debug_name, "kvm-%u", current->pid); 180 sprintf(debug_name, "kvm-%u", current->pid);
187 181
@@ -195,13 +189,11 @@ struct kvm *kvm_arch_create_vm(void)
195 debug_register_view(kvm->arch.dbf, &debug_sprintf_view); 189 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
196 VM_EVENT(kvm, 3, "%s", "vm created"); 190 VM_EVENT(kvm, 3, "%s", "vm created");
197 191
198 return kvm; 192 return 0;
199out_nodbf: 193out_nodbf:
200 free_page((unsigned long)(kvm->arch.sca)); 194 free_page((unsigned long)(kvm->arch.sca));
201out_nosca: 195out_err:
202 kfree(kvm); 196 return rc;
203out_nokvm:
204 return ERR_PTR(rc);
205} 197}
206 198
207void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) 199void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
@@ -240,11 +232,8 @@ void kvm_arch_sync_events(struct kvm *kvm)
240void kvm_arch_destroy_vm(struct kvm *kvm) 232void kvm_arch_destroy_vm(struct kvm *kvm)
241{ 233{
242 kvm_free_vcpus(kvm); 234 kvm_free_vcpus(kvm);
243 kvm_free_physmem(kvm);
244 free_page((unsigned long)(kvm->arch.sca)); 235 free_page((unsigned long)(kvm->arch.sca));
245 debug_unregister(kvm->arch.dbf); 236 debug_unregister(kvm->arch.dbf);
246 cleanup_srcu_struct(&kvm->srcu);
247 kfree(kvm);
248} 237}
249 238
250/* Section: vcpu related */ 239/* Section: vcpu related */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5daead833669..b7ee61d5bc81 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5961,13 +5961,8 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
5961 free_page((unsigned long)vcpu->arch.pio_data); 5961 free_page((unsigned long)vcpu->arch.pio_data);
5962} 5962}
5963 5963
5964struct kvm *kvm_arch_create_vm(void) 5964int kvm_arch_init_vm(struct kvm *kvm)
5965{ 5965{
5966 struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
5967
5968 if (!kvm)
5969 return ERR_PTR(-ENOMEM);
5970
5971 INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); 5966 INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
5972 INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); 5967 INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
5973 5968
@@ -5976,7 +5971,7 @@ struct kvm *kvm_arch_create_vm(void)
5976 5971
5977 spin_lock_init(&kvm->arch.tsc_write_lock); 5972 spin_lock_init(&kvm->arch.tsc_write_lock);
5978 5973
5979 return kvm; 5974 return 0;
5980} 5975}
5981 5976
5982static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu) 5977static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
@@ -6021,13 +6016,10 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
6021 kfree(kvm->arch.vpic); 6016 kfree(kvm->arch.vpic);
6022 kfree(kvm->arch.vioapic); 6017 kfree(kvm->arch.vioapic);
6023 kvm_free_vcpus(kvm); 6018 kvm_free_vcpus(kvm);
6024 kvm_free_physmem(kvm);
6025 if (kvm->arch.apic_access_page) 6019 if (kvm->arch.apic_access_page)
6026 put_page(kvm->arch.apic_access_page); 6020 put_page(kvm->arch.apic_access_page);
6027 if (kvm->arch.ept_identity_pagetable) 6021 if (kvm->arch.ept_identity_pagetable)
6028 put_page(kvm->arch.ept_identity_pagetable); 6022 put_page(kvm->arch.ept_identity_pagetable);
6029 cleanup_srcu_struct(&kvm->srcu);
6030 kfree(kvm);
6031} 6023}
6032 6024
6033int kvm_arch_prepare_memory_region(struct kvm *kvm, 6025int kvm_arch_prepare_memory_region(struct kvm *kvm,
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index bcf71c7730f0..2d63f2c0137c 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -16,6 +16,7 @@
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/preempt.h> 17#include <linux/preempt.h>
18#include <linux/msi.h> 18#include <linux/msi.h>
19#include <linux/slab.h>
19#include <asm/signal.h> 20#include <asm/signal.h>
20 21
21#include <linux/kvm.h> 22#include <linux/kvm.h>
@@ -441,7 +442,19 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
441 442
442void kvm_free_physmem(struct kvm *kvm); 443void kvm_free_physmem(struct kvm *kvm);
443 444
444struct kvm *kvm_arch_create_vm(void); 445#ifndef __KVM_HAVE_ARCH_VM_ALLOC
446static inline struct kvm *kvm_arch_alloc_vm(void)
447{
448 return kzalloc(sizeof(struct kvm), GFP_KERNEL);
449}
450
451static inline void kvm_arch_free_vm(struct kvm *kvm)
452{
453 kfree(kvm);
454}
455#endif
456
457int kvm_arch_init_vm(struct kvm *kvm);
445void kvm_arch_destroy_vm(struct kvm *kvm); 458void kvm_arch_destroy_vm(struct kvm *kvm);
446void kvm_free_all_assigned_devices(struct kvm *kvm); 459void kvm_free_all_assigned_devices(struct kvm *kvm);
447void kvm_arch_sync_events(struct kvm *kvm); 460void kvm_arch_sync_events(struct kvm *kvm);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index fce0578eab0e..4023264c4cd5 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -383,11 +383,15 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
383 383
384static struct kvm *kvm_create_vm(void) 384static struct kvm *kvm_create_vm(void)
385{ 385{
386 int r = 0, i; 386 int r, i;
387 struct kvm *kvm = kvm_arch_create_vm(); 387 struct kvm *kvm = kvm_arch_alloc_vm();
388 388
389 if (IS_ERR(kvm)) 389 if (!kvm)
390 goto out; 390 return ERR_PTR(-ENOMEM);
391
392 r = kvm_arch_init_vm(kvm);
393 if (r)
394 goto out_err_nodisable;
391 395
392 r = hardware_enable_all(); 396 r = hardware_enable_all();
393 if (r) 397 if (r)
@@ -427,7 +431,7 @@ static struct kvm *kvm_create_vm(void)
427 spin_lock(&kvm_lock); 431 spin_lock(&kvm_lock);
428 list_add(&kvm->vm_list, &vm_list); 432 list_add(&kvm->vm_list, &vm_list);
429 spin_unlock(&kvm_lock); 433 spin_unlock(&kvm_lock);
430out: 434
431 return kvm; 435 return kvm;
432 436
433out_err: 437out_err:
@@ -438,7 +442,7 @@ out_err_nodisable:
438 for (i = 0; i < KVM_NR_BUSES; i++) 442 for (i = 0; i < KVM_NR_BUSES; i++)
439 kfree(kvm->buses[i]); 443 kfree(kvm->buses[i]);
440 kfree(kvm->memslots); 444 kfree(kvm->memslots);
441 kfree(kvm); 445 kvm_arch_free_vm(kvm);
442 return ERR_PTR(r); 446 return ERR_PTR(r);
443} 447}
444 448
@@ -512,6 +516,9 @@ static void kvm_destroy_vm(struct kvm *kvm)
512 kvm_arch_flush_shadow(kvm); 516 kvm_arch_flush_shadow(kvm);
513#endif 517#endif
514 kvm_arch_destroy_vm(kvm); 518 kvm_arch_destroy_vm(kvm);
519 kvm_free_physmem(kvm);
520 cleanup_srcu_struct(&kvm->srcu);
521 kvm_arch_free_vm(kvm);
515 hardware_disable_all(); 522 hardware_disable_all();
516 mmdrop(mm); 523 mmdrop(mm);
517} 524}