diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/coalesced_mmio.c | 8 | ||||
-rw-r--r-- | virt/kvm/ioapic.c | 8 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 39 |
3 files changed, 46 insertions, 9 deletions
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index 0352f81ecc0b..04d69cd7049b 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c | |||
@@ -92,6 +92,7 @@ static const struct kvm_io_device_ops coalesced_mmio_ops = { | |||
92 | int kvm_coalesced_mmio_init(struct kvm *kvm) | 92 | int kvm_coalesced_mmio_init(struct kvm *kvm) |
93 | { | 93 | { |
94 | struct kvm_coalesced_mmio_dev *dev; | 94 | struct kvm_coalesced_mmio_dev *dev; |
95 | int ret; | ||
95 | 96 | ||
96 | dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL); | 97 | dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL); |
97 | if (!dev) | 98 | if (!dev) |
@@ -100,9 +101,12 @@ int kvm_coalesced_mmio_init(struct kvm *kvm) | |||
100 | kvm_iodevice_init(&dev->dev, &coalesced_mmio_ops); | 101 | kvm_iodevice_init(&dev->dev, &coalesced_mmio_ops); |
101 | dev->kvm = kvm; | 102 | dev->kvm = kvm; |
102 | kvm->coalesced_mmio_dev = dev; | 103 | kvm->coalesced_mmio_dev = dev; |
103 | kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &dev->dev); | ||
104 | 104 | ||
105 | return 0; | 105 | ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &dev->dev); |
106 | if (ret < 0) | ||
107 | kfree(dev); | ||
108 | |||
109 | return ret; | ||
106 | } | 110 | } |
107 | 111 | ||
108 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, | 112 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, |
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index b91fbb215447..fa05f67423ab 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -342,6 +342,7 @@ static const struct kvm_io_device_ops ioapic_mmio_ops = { | |||
342 | int kvm_ioapic_init(struct kvm *kvm) | 342 | int kvm_ioapic_init(struct kvm *kvm) |
343 | { | 343 | { |
344 | struct kvm_ioapic *ioapic; | 344 | struct kvm_ioapic *ioapic; |
345 | int ret; | ||
345 | 346 | ||
346 | ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL); | 347 | ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL); |
347 | if (!ioapic) | 348 | if (!ioapic) |
@@ -350,7 +351,10 @@ int kvm_ioapic_init(struct kvm *kvm) | |||
350 | kvm_ioapic_reset(ioapic); | 351 | kvm_ioapic_reset(ioapic); |
351 | kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops); | 352 | kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops); |
352 | ioapic->kvm = kvm; | 353 | ioapic->kvm = kvm; |
353 | kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &ioapic->dev); | 354 | ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &ioapic->dev); |
354 | return 0; | 355 | if (ret < 0) |
356 | kfree(ioapic); | ||
357 | |||
358 | return ret; | ||
355 | } | 359 | } |
356 | 360 | ||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index fc1b58a72757..9c2fd025b8ae 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -2533,21 +2533,50 @@ int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len, void *val) | |||
2533 | return -EOPNOTSUPP; | 2533 | return -EOPNOTSUPP; |
2534 | } | 2534 | } |
2535 | 2535 | ||
2536 | void kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus, | 2536 | int kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus, |
2537 | struct kvm_io_device *dev) | 2537 | struct kvm_io_device *dev) |
2538 | { | 2538 | { |
2539 | int ret; | ||
2540 | |||
2539 | down_write(&kvm->slots_lock); | 2541 | down_write(&kvm->slots_lock); |
2540 | __kvm_io_bus_register_dev(bus, dev); | 2542 | ret = __kvm_io_bus_register_dev(bus, dev); |
2541 | up_write(&kvm->slots_lock); | 2543 | up_write(&kvm->slots_lock); |
2544 | |||
2545 | return ret; | ||
2542 | } | 2546 | } |
2543 | 2547 | ||
2544 | /* An unlocked version. Caller must have write lock on slots_lock. */ | 2548 | /* An unlocked version. Caller must have write lock on slots_lock. */ |
2545 | void __kvm_io_bus_register_dev(struct kvm_io_bus *bus, | 2549 | int __kvm_io_bus_register_dev(struct kvm_io_bus *bus, |
2546 | struct kvm_io_device *dev) | 2550 | struct kvm_io_device *dev) |
2547 | { | 2551 | { |
2548 | BUG_ON(bus->dev_count > (NR_IOBUS_DEVS-1)); | 2552 | if (bus->dev_count > NR_IOBUS_DEVS-1) |
2553 | return -ENOSPC; | ||
2549 | 2554 | ||
2550 | bus->devs[bus->dev_count++] = dev; | 2555 | bus->devs[bus->dev_count++] = dev; |
2556 | |||
2557 | return 0; | ||
2558 | } | ||
2559 | |||
2560 | void kvm_io_bus_unregister_dev(struct kvm *kvm, | ||
2561 | struct kvm_io_bus *bus, | ||
2562 | struct kvm_io_device *dev) | ||
2563 | { | ||
2564 | down_write(&kvm->slots_lock); | ||
2565 | __kvm_io_bus_unregister_dev(bus, dev); | ||
2566 | up_write(&kvm->slots_lock); | ||
2567 | } | ||
2568 | |||
2569 | /* An unlocked version. Caller must have write lock on slots_lock. */ | ||
2570 | void __kvm_io_bus_unregister_dev(struct kvm_io_bus *bus, | ||
2571 | struct kvm_io_device *dev) | ||
2572 | { | ||
2573 | int i; | ||
2574 | |||
2575 | for (i = 0; i < bus->dev_count; i++) | ||
2576 | if (bus->devs[i] == dev) { | ||
2577 | bus->devs[i] = bus->devs[--bus->dev_count]; | ||
2578 | break; | ||
2579 | } | ||
2551 | } | 2580 | } |
2552 | 2581 | ||
2553 | static struct notifier_block kvm_cpu_notifier = { | 2582 | static struct notifier_block kvm_cpu_notifier = { |