Commit 72bb2fcd authored by Wei Yongjun's avatar Wei Yongjun Committed by Marcelo Tosatti

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: default avatarWei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 1ae77bad
...@@ -543,3 +543,14 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm) ...@@ -543,3 +543,14 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
return s; 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);
}
}
...@@ -75,6 +75,7 @@ struct kvm_pic { ...@@ -75,6 +75,7 @@ struct kvm_pic {
}; };
struct kvm_pic *kvm_create_pic(struct kvm *kvm); struct kvm_pic *kvm_create_pic(struct kvm *kvm);
void kvm_destroy_pic(struct kvm *kvm);
int kvm_pic_read_irq(struct kvm *kvm); int kvm_pic_read_irq(struct kvm *kvm);
void kvm_pic_update_irq(struct kvm_pic *s); void kvm_pic_update_irq(struct kvm_pic *s);
void kvm_pic_clear_isr_ack(struct kvm *kvm); void kvm_pic_clear_isr_ack(struct kvm *kvm);
......
...@@ -2771,6 +2771,8 @@ long kvm_arch_vm_ioctl(struct file *filp, ...@@ -2771,6 +2771,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (vpic) { if (vpic) {
r = kvm_ioapic_init(kvm); r = kvm_ioapic_init(kvm);
if (r) { if (r) {
kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS,
&vpic->dev);
kfree(vpic); kfree(vpic);
goto create_irqchip_unlock; goto create_irqchip_unlock;
} }
...@@ -2782,10 +2784,8 @@ long kvm_arch_vm_ioctl(struct file *filp, ...@@ -2782,10 +2784,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = kvm_setup_default_irq_routing(kvm); r = kvm_setup_default_irq_routing(kvm);
if (r) { if (r) {
mutex_lock(&kvm->irq_lock); mutex_lock(&kvm->irq_lock);
kfree(kvm->arch.vpic); kvm_ioapic_destroy(kvm);
kfree(kvm->arch.vioapic); kvm_destroy_pic(kvm);
kvm->arch.vpic = NULL;
kvm->arch.vioapic = NULL;
mutex_unlock(&kvm->irq_lock); mutex_unlock(&kvm->irq_lock);
} }
create_irqchip_unlock: create_irqchip_unlock:
......
...@@ -401,6 +401,17 @@ int kvm_ioapic_init(struct kvm *kvm) ...@@ -401,6 +401,17 @@ int kvm_ioapic_init(struct kvm *kvm)
return ret; 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) int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
{ {
struct kvm_ioapic *ioapic = ioapic_irqchip(kvm); struct kvm_ioapic *ioapic = ioapic_irqchip(kvm);
......
...@@ -72,6 +72,7 @@ int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, ...@@ -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); 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); void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
int kvm_ioapic_init(struct kvm *kvm); 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); int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
void kvm_ioapic_reset(struct kvm_ioapic *ioapic); void kvm_ioapic_reset(struct kvm_ioapic *ioapic);
int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment