aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/i8254.c
diff options
context:
space:
mode:
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)