aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2009-12-23 11:35:24 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2010-03-01 10:35:45 -0500
commite93f8a0f821e290ac5149830110a5f704db7a1fc (patch)
treef88a5e97286031a8105d63a069a4131b74dab113 /virt/kvm/kvm_main.c
parenta983fb238728e1123177e8058d4f644b949a7d05 (diff)
KVM: convert io_bus to SRCU
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c106
1 files changed, 63 insertions, 43 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c680f7b64c6f..659bc12ad16a 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -85,6 +85,8 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
85static int hardware_enable_all(void); 85static int hardware_enable_all(void);
86static void hardware_disable_all(void); 86static void hardware_disable_all(void);
87 87
88static void kvm_io_bus_destroy(struct kvm_io_bus *bus);
89
88static bool kvm_rebooting; 90static bool kvm_rebooting;
89 91
90static bool largepages_enabled = true; 92static bool largepages_enabled = true;
@@ -367,7 +369,7 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
367 369
368static struct kvm *kvm_create_vm(void) 370static struct kvm *kvm_create_vm(void)
369{ 371{
370 int r = 0; 372 int r = 0, i;
371 struct kvm *kvm = kvm_arch_create_vm(); 373 struct kvm *kvm = kvm_arch_create_vm();
372#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET 374#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
373 struct page *page; 375 struct page *page;
@@ -391,6 +393,14 @@ static struct kvm *kvm_create_vm(void)
391 goto out_err; 393 goto out_err;
392 if (init_srcu_struct(&kvm->srcu)) 394 if (init_srcu_struct(&kvm->srcu))
393 goto out_err; 395 goto out_err;
396 for (i = 0; i < KVM_NR_BUSES; i++) {
397 kvm->buses[i] = kzalloc(sizeof(struct kvm_io_bus),
398 GFP_KERNEL);
399 if (!kvm->buses[i]) {
400 cleanup_srcu_struct(&kvm->srcu);
401 goto out_err;
402 }
403 }
394 404
395#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET 405#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
396 page = alloc_page(GFP_KERNEL | __GFP_ZERO); 406 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
@@ -416,11 +426,9 @@ static struct kvm *kvm_create_vm(void)
416 atomic_inc(&kvm->mm->mm_count); 426 atomic_inc(&kvm->mm->mm_count);
417 spin_lock_init(&kvm->mmu_lock); 427 spin_lock_init(&kvm->mmu_lock);
418 spin_lock_init(&kvm->requests_lock); 428 spin_lock_init(&kvm->requests_lock);
419 kvm_io_bus_init(&kvm->pio_bus);
420 kvm_eventfd_init(kvm); 429 kvm_eventfd_init(kvm);
421 mutex_init(&kvm->lock); 430 mutex_init(&kvm->lock);
422 mutex_init(&kvm->irq_lock); 431 mutex_init(&kvm->irq_lock);
423 kvm_io_bus_init(&kvm->mmio_bus);
424 init_rwsem(&kvm->slots_lock); 432 init_rwsem(&kvm->slots_lock);
425 atomic_set(&kvm->users_count, 1); 433 atomic_set(&kvm->users_count, 1);
426 spin_lock(&kvm_lock); 434 spin_lock(&kvm_lock);
@@ -435,6 +443,8 @@ out:
435out_err: 443out_err:
436 hardware_disable_all(); 444 hardware_disable_all();
437out_err_nodisable: 445out_err_nodisable:
446 for (i = 0; i < KVM_NR_BUSES; i++)
447 kfree(kvm->buses[i]);
438 kfree(kvm->memslots); 448 kfree(kvm->memslots);
439 kfree(kvm); 449 kfree(kvm);
440 return ERR_PTR(r); 450 return ERR_PTR(r);
@@ -480,6 +490,7 @@ void kvm_free_physmem(struct kvm *kvm)
480 490
481static void kvm_destroy_vm(struct kvm *kvm) 491static void kvm_destroy_vm(struct kvm *kvm)
482{ 492{
493 int i;
483 struct mm_struct *mm = kvm->mm; 494 struct mm_struct *mm = kvm->mm;
484 495
485 kvm_arch_sync_events(kvm); 496 kvm_arch_sync_events(kvm);
@@ -487,8 +498,8 @@ static void kvm_destroy_vm(struct kvm *kvm)
487 list_del(&kvm->vm_list); 498 list_del(&kvm->vm_list);
488 spin_unlock(&kvm_lock); 499 spin_unlock(&kvm_lock);
489 kvm_free_irq_routing(kvm); 500 kvm_free_irq_routing(kvm);
490 kvm_io_bus_destroy(&kvm->pio_bus); 501 for (i = 0; i < KVM_NR_BUSES; i++)
491 kvm_io_bus_destroy(&kvm->mmio_bus); 502 kvm_io_bus_destroy(kvm->buses[i]);
492 kvm_coalesced_mmio_free(kvm); 503 kvm_coalesced_mmio_free(kvm);
493#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER) 504#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
494 mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm); 505 mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
@@ -1949,12 +1960,7 @@ static struct notifier_block kvm_reboot_notifier = {
1949 .priority = 0, 1960 .priority = 0,
1950}; 1961};
1951 1962
1952void kvm_io_bus_init(struct kvm_io_bus *bus) 1963static void kvm_io_bus_destroy(struct kvm_io_bus *bus)
1953{
1954 memset(bus, 0, sizeof(*bus));
1955}
1956
1957void kvm_io_bus_destroy(struct kvm_io_bus *bus)
1958{ 1964{
1959 int i; 1965 int i;
1960 1966
@@ -1963,13 +1969,15 @@ void kvm_io_bus_destroy(struct kvm_io_bus *bus)
1963 1969
1964 kvm_iodevice_destructor(pos); 1970 kvm_iodevice_destructor(pos);
1965 } 1971 }
1972 kfree(bus);
1966} 1973}
1967 1974
1968/* kvm_io_bus_write - called under kvm->slots_lock */ 1975/* kvm_io_bus_write - called under kvm->slots_lock */
1969int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr, 1976int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
1970 int len, const void *val) 1977 int len, const void *val)
1971{ 1978{
1972 int i; 1979 int i;
1980 struct kvm_io_bus *bus = rcu_dereference(kvm->buses[bus_idx]);
1973 for (i = 0; i < bus->dev_count; i++) 1981 for (i = 0; i < bus->dev_count; i++)
1974 if (!kvm_iodevice_write(bus->devs[i], addr, len, val)) 1982 if (!kvm_iodevice_write(bus->devs[i], addr, len, val))
1975 return 0; 1983 return 0;
@@ -1977,59 +1985,71 @@ int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr,
1977} 1985}
1978 1986
1979/* kvm_io_bus_read - called under kvm->slots_lock */ 1987/* kvm_io_bus_read - called under kvm->slots_lock */
1980int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len, void *val) 1988int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
1989 int len, void *val)
1981{ 1990{
1982 int i; 1991 int i;
1992 struct kvm_io_bus *bus = rcu_dereference(kvm->buses[bus_idx]);
1993
1983 for (i = 0; i < bus->dev_count; i++) 1994 for (i = 0; i < bus->dev_count; i++)
1984 if (!kvm_iodevice_read(bus->devs[i], addr, len, val)) 1995 if (!kvm_iodevice_read(bus->devs[i], addr, len, val))
1985 return 0; 1996 return 0;
1986 return -EOPNOTSUPP; 1997 return -EOPNOTSUPP;
1987} 1998}
1988 1999
1989int kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus, 2000/* Caller must have write lock on slots_lock. */
1990 struct kvm_io_device *dev) 2001int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx,
2002 struct kvm_io_device *dev)
1991{ 2003{
1992 int ret; 2004 struct kvm_io_bus *new_bus, *bus;
1993
1994 down_write(&kvm->slots_lock);
1995 ret = __kvm_io_bus_register_dev(bus, dev);
1996 up_write(&kvm->slots_lock);
1997 2005
1998 return ret; 2006 bus = kvm->buses[bus_idx];
1999}
2000
2001/* An unlocked version. Caller must have write lock on slots_lock. */
2002int __kvm_io_bus_register_dev(struct kvm_io_bus *bus,
2003 struct kvm_io_device *dev)
2004{
2005 if (bus->dev_count > NR_IOBUS_DEVS-1) 2007 if (bus->dev_count > NR_IOBUS_DEVS-1)
2006 return -ENOSPC; 2008 return -ENOSPC;
2007 2009
2008 bus->devs[bus->dev_count++] = dev; 2010 new_bus = kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL);
2011 if (!new_bus)
2012 return -ENOMEM;
2013 memcpy(new_bus, bus, sizeof(struct kvm_io_bus));
2014 new_bus->devs[new_bus->dev_count++] = dev;
2015 rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
2016 synchronize_srcu_expedited(&kvm->srcu);
2017 kfree(bus);
2009 2018
2010 return 0; 2019 return 0;
2011} 2020}
2012 2021
2013void kvm_io_bus_unregister_dev(struct kvm *kvm, 2022/* Caller must have write lock on slots_lock. */
2014 struct kvm_io_bus *bus, 2023int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
2015 struct kvm_io_device *dev) 2024 struct kvm_io_device *dev)
2016{ 2025{
2017 down_write(&kvm->slots_lock); 2026 int i, r;
2018 __kvm_io_bus_unregister_dev(bus, dev); 2027 struct kvm_io_bus *new_bus, *bus;
2019 up_write(&kvm->slots_lock);
2020}
2021 2028
2022/* An unlocked version. Caller must have write lock on slots_lock. */ 2029 new_bus = kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL);
2023void __kvm_io_bus_unregister_dev(struct kvm_io_bus *bus, 2030 if (!new_bus)
2024 struct kvm_io_device *dev) 2031 return -ENOMEM;
2025{
2026 int i;
2027 2032
2028 for (i = 0; i < bus->dev_count; i++) 2033 bus = kvm->buses[bus_idx];
2029 if (bus->devs[i] == dev) { 2034 memcpy(new_bus, bus, sizeof(struct kvm_io_bus));
2030 bus->devs[i] = bus->devs[--bus->dev_count]; 2035
2036 r = -ENOENT;
2037 for (i = 0; i < new_bus->dev_count; i++)
2038 if (new_bus->devs[i] == dev) {
2039 r = 0;
2040 new_bus->devs[i] = new_bus->devs[--new_bus->dev_count];
2031 break; 2041 break;
2032 } 2042 }
2043
2044 if (r) {
2045 kfree(new_bus);
2046 return r;
2047 }
2048
2049 rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
2050 synchronize_srcu_expedited(&kvm->srcu);
2051 kfree(bus);
2052 return r;
2033} 2053}
2034 2054
2035static struct notifier_block kvm_cpu_notifier = { 2055static struct notifier_block kvm_cpu_notifier = {