diff options
-rw-r--r-- | arch/x86/kvm/i8254.c | 20 | ||||
-rw-r--r-- | arch/x86/kvm/i8259.c | 9 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 10 | ||||
-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 |
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 | |||
657 | fail_unregister: | ||
658 | __kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->dev); | ||
659 | |||
660 | fail: | ||
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 | ||
652 | void kvm_free_pit(struct kvm *kvm) | 668 | void 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 = { | |||
539 | struct kvm_pic *kvm_create_pic(struct kvm *kvm) | 539 | struct 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); |
65 | int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len, | 65 | int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len, |
66 | void *val); | 66 | void *val); |
67 | void __kvm_io_bus_register_dev(struct kvm_io_bus *bus, | 67 | int __kvm_io_bus_register_dev(struct kvm_io_bus *bus, |
68 | struct kvm_io_device *dev); | ||
69 | int kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus, | ||
70 | struct kvm_io_device *dev); | ||
71 | void __kvm_io_bus_unregister_dev(struct kvm_io_bus *bus, | ||
72 | struct kvm_io_device *dev); | ||
73 | void 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); |
69 | void kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus, | ||
70 | struct kvm_io_device *dev); | ||
71 | 75 | ||
72 | struct kvm_vcpu { | 76 | struct 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 = { | |||
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 = { |