KVM: cleanup the failure path of KVM_CREATE_IRQCHIP ioctrl
authorWei Yongjun <yjwei@cn.fujitsu.com>
Tue, 9 Feb 2010 02:33:03 +0000 (10:33 +0800)
committerMarcelo Tosatti <mtosatti@redhat.com>
Mon, 1 Mar 2010 15:36:10 +0000 (12:36 -0300)
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>
arch/x86/kvm/i8259.c
arch/x86/kvm/irq.h
arch/x86/kvm/x86.c
virt/kvm/ioapic.c
virt/kvm/ioapic.h

index d5753a75d58c67799c14bc6144e09d543be7e7ec..a3711f9e580fe25ba44952b491247b8813dc0c54 100644 (file)
@@ -543,3 +543,14 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
 
        return s;
 }
+
+void kvm_destroy_pic(struct kvm *kvm)
+{
+       struct kvm_pic *vpic = kvm->arch.vpic;
+
+       if (vpic) {
+               kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &vpic->dev);
+               kvm->arch.vpic = NULL;
+               kfree(vpic);
+       }
+}
index be399e207d57943ac74a6967e3dd21776b262dee..0b71d480ebf1f161e240bd62b654292f57a6bd0f 100644 (file)
@@ -75,6 +75,7 @@ struct kvm_pic {
 };
 
 struct kvm_pic *kvm_create_pic(struct kvm *kvm);
+void kvm_destroy_pic(struct kvm *kvm);
 int kvm_pic_read_irq(struct kvm *kvm);
 void kvm_pic_update_irq(struct kvm_pic *s);
 void kvm_pic_clear_isr_ack(struct kvm *kvm);
index bd3161c6daed04b8a24d676efccc74f78043253e..b2f91b9af00d59991d57e70b123d6b1de03b031e 100644 (file)
@@ -2771,6 +2771,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
                if (vpic) {
                        r = kvm_ioapic_init(kvm);
                        if (r) {
+                               kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS,
+                                                         &vpic->dev);
                                kfree(vpic);
                                goto create_irqchip_unlock;
                        }
@@ -2782,10 +2784,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
                r = kvm_setup_default_irq_routing(kvm);
                if (r) {
                        mutex_lock(&kvm->irq_lock);
-                       kfree(kvm->arch.vpic);
-                       kfree(kvm->arch.vioapic);
-                       kvm->arch.vpic = NULL;
-                       kvm->arch.vioapic = NULL;
+                       kvm_ioapic_destroy(kvm);
+                       kvm_destroy_pic(kvm);
                        mutex_unlock(&kvm->irq_lock);
                }
        create_irqchip_unlock:
index f3d06934ae6d2f544d6eca8f2a5753788f34a26f..3db15a807f8064149a8b3bf5f4fcdd349697cdc5 100644 (file)
@@ -401,6 +401,17 @@ int kvm_ioapic_init(struct kvm *kvm)
        return ret;
 }
 
+void kvm_ioapic_destroy(struct kvm *kvm)
+{
+       struct kvm_ioapic *ioapic = kvm->arch.vioapic;
+
+       if (ioapic) {
+               kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &ioapic->dev);
+               kvm->arch.vioapic = NULL;
+               kfree(ioapic);
+       }
+}
+
 int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
 {
        struct kvm_ioapic *ioapic = ioapic_irqchip(kvm);
index a505ce9054f36d9163a26a0ab1bfc09e7ff8d439..8a751b78a4301bffda6139ce92cfda2c5d7317f5 100644 (file)
@@ -72,6 +72,7 @@ int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
 int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
 void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
 int kvm_ioapic_init(struct kvm *kvm);
+void kvm_ioapic_destroy(struct kvm *kvm);
 int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
 void kvm_ioapic_reset(struct kvm_ioapic *ioapic);
 int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,