Commit 72bb2fcd23afe8db53b47e8f9edd736c517ba532
Committed by
Marcelo Tosatti
1 parent
1ae77badc2
Exists in
master
and in
7 other branches
KVM: cleanup the failure path of KVM_CREATE_IRQCHIP ioctrl
If we fail to init ioapic device or the fail to setup the default irq routing, the device register by kvm_create_pic() and kvm_ioapic_init() remain unregister. This patch fixed to do this. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Showing 5 changed files with 28 additions and 4 deletions Side-by-side Diff
arch/x86/kvm/i8259.c
... | ... | @@ -543,4 +543,15 @@ |
543 | 543 | |
544 | 544 | return s; |
545 | 545 | } |
546 | + | |
547 | +void kvm_destroy_pic(struct kvm *kvm) | |
548 | +{ | |
549 | + struct kvm_pic *vpic = kvm->arch.vpic; | |
550 | + | |
551 | + if (vpic) { | |
552 | + kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &vpic->dev); | |
553 | + kvm->arch.vpic = NULL; | |
554 | + kfree(vpic); | |
555 | + } | |
556 | +} |
arch/x86/kvm/irq.h
arch/x86/kvm/x86.c
... | ... | @@ -2771,6 +2771,8 @@ |
2771 | 2771 | if (vpic) { |
2772 | 2772 | r = kvm_ioapic_init(kvm); |
2773 | 2773 | if (r) { |
2774 | + kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, | |
2775 | + &vpic->dev); | |
2774 | 2776 | kfree(vpic); |
2775 | 2777 | goto create_irqchip_unlock; |
2776 | 2778 | } |
... | ... | @@ -2782,10 +2784,8 @@ |
2782 | 2784 | r = kvm_setup_default_irq_routing(kvm); |
2783 | 2785 | if (r) { |
2784 | 2786 | mutex_lock(&kvm->irq_lock); |
2785 | - kfree(kvm->arch.vpic); | |
2786 | - kfree(kvm->arch.vioapic); | |
2787 | - kvm->arch.vpic = NULL; | |
2788 | - kvm->arch.vioapic = NULL; | |
2787 | + kvm_ioapic_destroy(kvm); | |
2788 | + kvm_destroy_pic(kvm); | |
2789 | 2789 | mutex_unlock(&kvm->irq_lock); |
2790 | 2790 | } |
2791 | 2791 | create_irqchip_unlock: |
virt/kvm/ioapic.c
... | ... | @@ -401,6 +401,17 @@ |
401 | 401 | return ret; |
402 | 402 | } |
403 | 403 | |
404 | +void kvm_ioapic_destroy(struct kvm *kvm) | |
405 | +{ | |
406 | + struct kvm_ioapic *ioapic = kvm->arch.vioapic; | |
407 | + | |
408 | + if (ioapic) { | |
409 | + kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &ioapic->dev); | |
410 | + kvm->arch.vioapic = NULL; | |
411 | + kfree(ioapic); | |
412 | + } | |
413 | +} | |
414 | + | |
404 | 415 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) |
405 | 416 | { |
406 | 417 | struct kvm_ioapic *ioapic = ioapic_irqchip(kvm); |
virt/kvm/ioapic.h
... | ... | @@ -72,6 +72,7 @@ |
72 | 72 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); |
73 | 73 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); |
74 | 74 | int kvm_ioapic_init(struct kvm *kvm); |
75 | +void kvm_ioapic_destroy(struct kvm *kvm); | |
75 | 76 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); |
76 | 77 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); |
77 | 78 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, |