aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/kvm_main.c90
1 files changed, 78 insertions, 12 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 38e4d2c34ac1..70c8cbea0a99 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -69,6 +69,8 @@ DEFINE_SPINLOCK(kvm_lock);
69LIST_HEAD(vm_list); 69LIST_HEAD(vm_list);
70 70
71static cpumask_var_t cpus_hardware_enabled; 71static cpumask_var_t cpus_hardware_enabled;
72static int kvm_usage_count = 0;
73static atomic_t hardware_enable_failed;
72 74
73struct kmem_cache *kvm_vcpu_cache; 75struct kmem_cache *kvm_vcpu_cache;
74EXPORT_SYMBOL_GPL(kvm_vcpu_cache); 76EXPORT_SYMBOL_GPL(kvm_vcpu_cache);
@@ -79,6 +81,8 @@ struct dentry *kvm_debugfs_dir;
79 81
80static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, 82static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
81 unsigned long arg); 83 unsigned long arg);
84static int hardware_enable_all(void);
85static void hardware_disable_all(void);
82 86
83static bool kvm_rebooting; 87static bool kvm_rebooting;
84 88
@@ -339,6 +343,7 @@ static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
339 343
340static struct kvm *kvm_create_vm(void) 344static struct kvm *kvm_create_vm(void)
341{ 345{
346 int r = 0;
342 struct kvm *kvm = kvm_arch_create_vm(); 347 struct kvm *kvm = kvm_arch_create_vm();
343#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET 348#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
344 struct page *page; 349 struct page *page;
@@ -346,6 +351,11 @@ static struct kvm *kvm_create_vm(void)
346 351
347 if (IS_ERR(kvm)) 352 if (IS_ERR(kvm))
348 goto out; 353 goto out;
354
355 r = hardware_enable_all();
356 if (r)
357 goto out_err_nodisable;
358
349#ifdef CONFIG_HAVE_KVM_IRQCHIP 359#ifdef CONFIG_HAVE_KVM_IRQCHIP
350 INIT_HLIST_HEAD(&kvm->mask_notifier_list); 360 INIT_HLIST_HEAD(&kvm->mask_notifier_list);
351 INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); 361 INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list);
@@ -354,8 +364,8 @@ static struct kvm *kvm_create_vm(void)
354#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET 364#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
355 page = alloc_page(GFP_KERNEL | __GFP_ZERO); 365 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
356 if (!page) { 366 if (!page) {
357 kfree(kvm); 367 r = -ENOMEM;
358 return ERR_PTR(-ENOMEM); 368 goto out_err;
359 } 369 }
360 kvm->coalesced_mmio_ring = 370 kvm->coalesced_mmio_ring =
361 (struct kvm_coalesced_mmio_ring *)page_address(page); 371 (struct kvm_coalesced_mmio_ring *)page_address(page);
@@ -363,15 +373,13 @@ static struct kvm *kvm_create_vm(void)
363 373
364#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER) 374#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
365 { 375 {
366 int err;
367 kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops; 376 kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops;
368 err = mmu_notifier_register(&kvm->mmu_notifier, current->mm); 377 r = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
369 if (err) { 378 if (r) {
370#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET 379#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
371 put_page(page); 380 put_page(page);
372#endif 381#endif
373 kfree(kvm); 382 goto out_err;
374 return ERR_PTR(err);
375 } 383 }
376 } 384 }
377#endif 385#endif
@@ -395,6 +403,12 @@ static struct kvm *kvm_create_vm(void)
395#endif 403#endif
396out: 404out:
397 return kvm; 405 return kvm;
406
407out_err:
408 hardware_disable_all();
409out_err_nodisable:
410 kfree(kvm);
411 return ERR_PTR(r);
398} 412}
399 413
400/* 414/*
@@ -453,6 +467,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
453 kvm_arch_flush_shadow(kvm); 467 kvm_arch_flush_shadow(kvm);
454#endif 468#endif
455 kvm_arch_destroy_vm(kvm); 469 kvm_arch_destroy_vm(kvm);
470 hardware_disable_all();
456 mmdrop(mm); 471 mmdrop(mm);
457} 472}
458 473
@@ -1644,11 +1659,21 @@ static struct miscdevice kvm_dev = {
1644static void hardware_enable(void *junk) 1659static void hardware_enable(void *junk)
1645{ 1660{
1646 int cpu = raw_smp_processor_id(); 1661 int cpu = raw_smp_processor_id();
1662 int r;
1647 1663
1648 if (cpumask_test_cpu(cpu, cpus_hardware_enabled)) 1664 if (cpumask_test_cpu(cpu, cpus_hardware_enabled))
1649 return; 1665 return;
1666
1650 cpumask_set_cpu(cpu, cpus_hardware_enabled); 1667 cpumask_set_cpu(cpu, cpus_hardware_enabled);
1651 kvm_arch_hardware_enable(NULL); 1668
1669 r = kvm_arch_hardware_enable(NULL);
1670
1671 if (r) {
1672 cpumask_clear_cpu(cpu, cpus_hardware_enabled);
1673 atomic_inc(&hardware_enable_failed);
1674 printk(KERN_INFO "kvm: enabling virtualization on "
1675 "CPU%d failed\n", cpu);
1676 }
1652} 1677}
1653 1678
1654static void hardware_disable(void *junk) 1679static void hardware_disable(void *junk)
@@ -1661,11 +1686,52 @@ static void hardware_disable(void *junk)
1661 kvm_arch_hardware_disable(NULL); 1686 kvm_arch_hardware_disable(NULL);
1662} 1687}
1663 1688
1689static void hardware_disable_all_nolock(void)
1690{
1691 BUG_ON(!kvm_usage_count);
1692
1693 kvm_usage_count--;
1694 if (!kvm_usage_count)
1695 on_each_cpu(hardware_disable, NULL, 1);
1696}
1697
1698static void hardware_disable_all(void)
1699{
1700 spin_lock(&kvm_lock);
1701 hardware_disable_all_nolock();
1702 spin_unlock(&kvm_lock);
1703}
1704
1705static int hardware_enable_all(void)
1706{
1707 int r = 0;
1708
1709 spin_lock(&kvm_lock);
1710
1711 kvm_usage_count++;
1712 if (kvm_usage_count == 1) {
1713 atomic_set(&hardware_enable_failed, 0);
1714 on_each_cpu(hardware_enable, NULL, 1);
1715
1716 if (atomic_read(&hardware_enable_failed)) {
1717 hardware_disable_all_nolock();
1718 r = -EBUSY;
1719 }
1720 }
1721
1722 spin_unlock(&kvm_lock);
1723
1724 return r;
1725}
1726
1664static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, 1727static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
1665 void *v) 1728 void *v)
1666{ 1729{
1667 int cpu = (long)v; 1730 int cpu = (long)v;
1668 1731
1732 if (!kvm_usage_count)
1733 return NOTIFY_OK;
1734
1669 val &= ~CPU_TASKS_FROZEN; 1735 val &= ~CPU_TASKS_FROZEN;
1670 switch (val) { 1736 switch (val) {
1671 case CPU_DYING: 1737 case CPU_DYING:
@@ -1868,13 +1934,15 @@ static void kvm_exit_debug(void)
1868 1934
1869static int kvm_suspend(struct sys_device *dev, pm_message_t state) 1935static int kvm_suspend(struct sys_device *dev, pm_message_t state)
1870{ 1936{
1871 hardware_disable(NULL); 1937 if (kvm_usage_count)
1938 hardware_disable(NULL);
1872 return 0; 1939 return 0;
1873} 1940}
1874 1941
1875static int kvm_resume(struct sys_device *dev) 1942static int kvm_resume(struct sys_device *dev)
1876{ 1943{
1877 hardware_enable(NULL); 1944 if (kvm_usage_count)
1945 hardware_enable(NULL);
1878 return 0; 1946 return 0;
1879} 1947}
1880 1948
@@ -1949,7 +2017,6 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
1949 goto out_free_1; 2017 goto out_free_1;
1950 } 2018 }
1951 2019
1952 on_each_cpu(hardware_enable, NULL, 1);
1953 r = register_cpu_notifier(&kvm_cpu_notifier); 2020 r = register_cpu_notifier(&kvm_cpu_notifier);
1954 if (r) 2021 if (r)
1955 goto out_free_2; 2022 goto out_free_2;
@@ -1999,7 +2066,6 @@ out_free_3:
1999 unregister_reboot_notifier(&kvm_reboot_notifier); 2066 unregister_reboot_notifier(&kvm_reboot_notifier);
2000 unregister_cpu_notifier(&kvm_cpu_notifier); 2067 unregister_cpu_notifier(&kvm_cpu_notifier);
2001out_free_2: 2068out_free_2:
2002 on_each_cpu(hardware_disable, NULL, 1);
2003out_free_1: 2069out_free_1:
2004 kvm_arch_hardware_unsetup(); 2070 kvm_arch_hardware_unsetup();
2005out_free_0a: 2071out_free_0a: