aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/i8254.c20
-rw-r--r--arch/x86/kvm/i8259.c9
-rw-r--r--include/linux/kvm_host.h10
-rw-r--r--virt/kvm/coalesced_mmio.c8
-rw-r--r--virt/kvm/ioapic.c8
-rw-r--r--virt/kvm/kvm_main.c39
6 files changed, 79 insertions, 15 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 9b62c57ba6e4..137e54817102 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -605,6 +605,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
605{ 605{
606 struct kvm_pit *pit; 606 struct kvm_pit *pit;
607 struct kvm_kpit_state *pit_state; 607 struct kvm_kpit_state *pit_state;
608 int ret;
608 609
609 pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL); 610 pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL);
610 if (!pit) 611 if (!pit)
@@ -639,14 +640,29 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
639 kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier); 640 kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
640 641
641 kvm_iodevice_init(&pit->dev, &pit_dev_ops); 642 kvm_iodevice_init(&pit->dev, &pit_dev_ops);
642 __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev); 643 ret = __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
644 if (ret < 0)
645 goto fail;
643 646
644 if (flags & KVM_PIT_SPEAKER_DUMMY) { 647 if (flags & KVM_PIT_SPEAKER_DUMMY) {
645 kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops); 648 kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops);
646 __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev); 649 ret = __kvm_io_bus_register_dev(&kvm->pio_bus,
650 &pit->speaker_dev);
651 if (ret < 0)
652 goto fail_unregister;
647 } 653 }
648 654
649 return pit; 655 return pit;
656
657fail_unregister:
658 __kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->dev);
659
660fail:
661 if (pit->irq_source_id >= 0)
662 kvm_free_irq_source_id(kvm, pit->irq_source_id);
663
664 kfree(pit);
665 return NULL;
650} 666}
651 667
652void kvm_free_pit(struct kvm *kvm) 668void kvm_free_pit(struct kvm *kvm)
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index e4bcbddecb36..daf4606b0293 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -539,6 +539,8 @@ static const struct kvm_io_device_ops picdev_ops = {
539struct kvm_pic *kvm_create_pic(struct kvm *kvm) 539struct kvm_pic *kvm_create_pic(struct kvm *kvm)
540{ 540{
541 struct kvm_pic *s; 541 struct kvm_pic *s;
542 int ret;
543
542 s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); 544 s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
543 if (!s) 545 if (!s)
544 return NULL; 546 return NULL;
@@ -555,6 +557,11 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
555 * Initialize PIO device 557 * Initialize PIO device
556 */ 558 */
557 kvm_iodevice_init(&s->dev, &picdev_ops); 559 kvm_iodevice_init(&s->dev, &picdev_ops);
558 kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &s->dev); 560 ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &s->dev);
561 if (ret < 0) {
562 kfree(s);
563 return NULL;
564 }
565
559 return s; 566 return s;
560} 567}
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 077e8bb875a9..983b0bdeb3ff 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -64,10 +64,14 @@ int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr, int len,
64 const void *val); 64 const void *val);
65int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len, 65int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len,
66 void *val); 66 void *val);
67void __kvm_io_bus_register_dev(struct kvm_io_bus *bus, 67int __kvm_io_bus_register_dev(struct kvm_io_bus *bus,
68 struct kvm_io_device *dev);
69int kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus,
70 struct kvm_io_device *dev);
71void __kvm_io_bus_unregister_dev(struct kvm_io_bus *bus,
72 struct kvm_io_device *dev);
73void kvm_io_bus_unregister_dev(struct kvm *kvm, struct kvm_io_bus *bus,
68 struct kvm_io_device *dev); 74 struct kvm_io_device *dev);
69void kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus,
70 struct kvm_io_device *dev);
71 75
72struct kvm_vcpu { 76struct kvm_vcpu {
73 struct kvm *kvm; 77 struct kvm *kvm;
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 = {
92int kvm_coalesced_mmio_init(struct kvm *kvm) 92int 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
108int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, 112int 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 = {
342int kvm_ioapic_init(struct kvm *kvm) 342int 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
2536void kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus, 2536int 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. */
2545void __kvm_io_bus_register_dev(struct kvm_io_bus *bus, 2549int __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
2560void 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. */
2570void __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
2553static struct notifier_block kvm_cpu_notifier = { 2582static struct notifier_block kvm_cpu_notifier = {