aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2009-09-15 05:37:46 -0400
committerAvi Kivity <avi@redhat.com>2009-12-03 02:32:10 -0500
commit10474ae8945ce08622fd1f3464e55bd817bf2376 (patch)
treed390843b5107e600fbbf745eb24d85d745fe449f /virt
parente8b3433a5c062e94e34cadb6144c10689a497bc3 (diff)
KVM: Activate Virtualization On Demand
X86 CPUs need to have some magic happening to enable the virtualization extensions on them. This magic can result in unpleasant results for users, like blocking other VMMs from working (vmx) or using invalid TLB entries (svm). Currently KVM activates virtualization when the respective kernel module is loaded. This blocks us from autoloading KVM modules without breaking other VMMs. To circumvent this problem at least a bit, this patch introduces on demand activation of virtualization. This means, that instead virtualization is enabled on creation of the first virtual machine and disabled on destruction of the last one. So using this, KVM can be easily autoloaded, while keeping other hypervisors usable. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
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: