aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorGregory Haskins <ghaskins@novell.com>2009-07-07 17:08:44 -0400
committerAvi Kivity <avi@redhat.com>2009-09-10 01:33:12 -0400
commit090b7aff27120cdae76a346a70db394844fea598 (patch)
tree4676410f57a44d7c0fba9d791fc77d7850ad1d51 /arch/x86/kvm
parentfef07aae9cd9ed82f94228c311b35360f1f38902 (diff)
KVM: make io_bus interface more robust
Today kvm_io_bus_regsiter_dev() returns void and will internally BUG_ON if it fails. We want to create dynamic MMIO/PIO entries driven from userspace later in the series, so we need to enhance the code to be more robust with the following changes: 1) Add a return value to the registration function 2) Fix up all the callsites to check the return code, handle any failures, and percolate the error up to the caller. 3) Add an unregister function that collapses holes in the array Signed-off-by: Gregory Haskins <ghaskins@novell.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/i8254.c20
-rw-r--r--arch/x86/kvm/i8259.c9
2 files changed, 26 insertions, 3 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}