aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/i8254.c
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/i8254.c
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/i8254.c')
-rw-r--r--arch/x86/kvm/i8254.c20
1 files changed, 18 insertions, 2 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)