aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2010-02-08 21:33:03 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2010-03-01 10:36:10 -0500
commit72bb2fcd23afe8db53b47e8f9edd736c517ba532 (patch)
treeb79884bcb50077fec7cb5615178cacbbf9e6ce04
parent1ae77badc2504d157800f10a81a58cc9c941e7cb (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.c11
-rw-r--r--arch/x86/kvm/irq.h1
-rw-r--r--arch/x86/kvm/x86.c8
-rw-r--r--virt/kvm/ioapic.c11
-rw-r--r--virt/kvm/ioapic.h1
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
547void 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
77struct kvm_pic *kvm_create_pic(struct kvm *kvm); 77struct kvm_pic *kvm_create_pic(struct kvm *kvm);
78void kvm_destroy_pic(struct kvm *kvm);
78int kvm_pic_read_irq(struct kvm *kvm); 79int kvm_pic_read_irq(struct kvm *kvm);
79void kvm_pic_update_irq(struct kvm_pic *s); 80void kvm_pic_update_irq(struct kvm_pic *s);
80void kvm_pic_clear_isr_ack(struct kvm *kvm); 81void 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
404void 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
404int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) 415int 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,
72int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); 72int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
73void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); 73void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
74int kvm_ioapic_init(struct kvm *kvm); 74int kvm_ioapic_init(struct kvm *kvm);
75void kvm_ioapic_destroy(struct kvm *kvm);
75int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); 76int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
76void kvm_ioapic_reset(struct kvm_ioapic *ioapic); 77void kvm_ioapic_reset(struct kvm_ioapic *ioapic);
77int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, 78int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,