diff options
author | Wei Yongjun <yjwei@cn.fujitsu.com> | 2010-02-08 21:33:03 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:36:10 -0500 |
commit | 72bb2fcd23afe8db53b47e8f9edd736c517ba532 (patch) | |
tree | b79884bcb50077fec7cb5615178cacbbf9e6ce04 | |
parent | 1ae77badc2504d157800f10a81a58cc9c941e7cb (diff) |
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>
-rw-r--r-- | arch/x86/kvm/i8259.c | 11 | ||||
-rw-r--r-- | arch/x86/kvm/irq.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 8 | ||||
-rw-r--r-- | virt/kvm/ioapic.c | 11 | ||||
-rw-r--r-- | virt/kvm/ioapic.h | 1 |
5 files changed, 28 insertions, 4 deletions
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index d5753a75d58c..a3711f9e580f 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -543,3 +543,14 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm) | |||
543 | 543 | ||
544 | return s; | 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 | } | ||
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index be399e207d57..0b71d480ebf1 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
@@ -75,6 +75,7 @@ struct kvm_pic { | |||
75 | }; | 75 | }; |
76 | 76 | ||
77 | struct kvm_pic *kvm_create_pic(struct kvm *kvm); | 77 | struct kvm_pic *kvm_create_pic(struct kvm *kvm); |
78 | void kvm_destroy_pic(struct kvm *kvm); | ||
78 | int kvm_pic_read_irq(struct kvm *kvm); | 79 | int kvm_pic_read_irq(struct kvm *kvm); |
79 | void kvm_pic_update_irq(struct kvm_pic *s); | 80 | void kvm_pic_update_irq(struct kvm_pic *s); |
80 | void kvm_pic_clear_isr_ack(struct kvm *kvm); | 81 | void kvm_pic_clear_isr_ack(struct kvm *kvm); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bd3161c6daed..b2f91b9af00d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2771,6 +2771,8 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
2771 | if (vpic) { | 2771 | if (vpic) { |
2772 | r = kvm_ioapic_init(kvm); | 2772 | r = kvm_ioapic_init(kvm); |
2773 | if (r) { | 2773 | if (r) { |
2774 | kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, | ||
2775 | &vpic->dev); | ||
2774 | kfree(vpic); | 2776 | kfree(vpic); |
2775 | goto create_irqchip_unlock; | 2777 | goto create_irqchip_unlock; |
2776 | } | 2778 | } |
@@ -2782,10 +2784,8 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
2782 | r = kvm_setup_default_irq_routing(kvm); | 2784 | r = kvm_setup_default_irq_routing(kvm); |
2783 | if (r) { | 2785 | if (r) { |
2784 | mutex_lock(&kvm->irq_lock); | 2786 | mutex_lock(&kvm->irq_lock); |
2785 | kfree(kvm->arch.vpic); | 2787 | kvm_ioapic_destroy(kvm); |
2786 | kfree(kvm->arch.vioapic); | 2788 | kvm_destroy_pic(kvm); |
2787 | kvm->arch.vpic = NULL; | ||
2788 | kvm->arch.vioapic = NULL; | ||
2789 | mutex_unlock(&kvm->irq_lock); | 2789 | mutex_unlock(&kvm->irq_lock); |
2790 | } | 2790 | } |
2791 | create_irqchip_unlock: | 2791 | create_irqchip_unlock: |
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index f3d06934ae6d..3db15a807f80 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -401,6 +401,17 @@ int kvm_ioapic_init(struct kvm *kvm) | |||
401 | return ret; | 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 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) | 415 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) |
405 | { | 416 | { |
406 | struct kvm_ioapic *ioapic = ioapic_irqchip(kvm); | 417 | struct kvm_ioapic *ioapic = ioapic_irqchip(kvm); |
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index a505ce9054f3..8a751b78a430 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h | |||
@@ -72,6 +72,7 @@ int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | |||
72 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); | 72 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); |
73 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); | 73 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); |
74 | int kvm_ioapic_init(struct kvm *kvm); | 74 | int kvm_ioapic_init(struct kvm *kvm); |
75 | void kvm_ioapic_destroy(struct kvm *kvm); | ||
75 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); | 76 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); |
76 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); | 77 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); |
77 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | 78 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, |