diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2009-06-04 14:08:24 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:32:49 -0400 |
commit | fa40a8214bb9bcae8d49c234c19d8b4a6c1f37ff (patch) | |
tree | 6449f27072f128a1c39faaaeef1787f754345aaf /arch/x86/kvm/lapic.c | |
parent | 60eead79ad8750f80384cbe48fc44edcc78a0305 (diff) |
KVM: switch irq injection/acking data structures to irq_lock
Protect irq injection/acking data structures with a separate irq_lock
mutex. This fixes the following deadlock:
CPU A CPU B
kvm_vm_ioctl_deassign_dev_irq()
mutex_lock(&kvm->lock); worker_thread()
-> kvm_deassign_irq() -> kvm_assigned_dev_interrupt_work_handler()
-> deassign_host_irq() mutex_lock(&kvm->lock);
-> cancel_work_sync() [blocked]
[gleb: fix ia64 path]
Reported-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index a23f42e550af..44f20cdb5709 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -424,7 +424,9 @@ static void apic_set_eoi(struct kvm_lapic *apic) | |||
424 | trigger_mode = IOAPIC_LEVEL_TRIG; | 424 | trigger_mode = IOAPIC_LEVEL_TRIG; |
425 | else | 425 | else |
426 | trigger_mode = IOAPIC_EDGE_TRIG; | 426 | trigger_mode = IOAPIC_EDGE_TRIG; |
427 | mutex_lock(&apic->vcpu->kvm->irq_lock); | ||
427 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | 428 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); |
429 | mutex_unlock(&apic->vcpu->kvm->irq_lock); | ||
428 | } | 430 | } |
429 | 431 | ||
430 | static void apic_send_ipi(struct kvm_lapic *apic) | 432 | static void apic_send_ipi(struct kvm_lapic *apic) |
@@ -448,7 +450,9 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
448 | irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, | 450 | irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, |
449 | irq.vector); | 451 | irq.vector); |
450 | 452 | ||
453 | mutex_lock(&apic->vcpu->kvm->irq_lock); | ||
451 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq); | 454 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq); |
455 | mutex_unlock(&apic->vcpu->kvm->irq_lock); | ||
452 | } | 456 | } |
453 | 457 | ||
454 | static u32 apic_get_tmcct(struct kvm_lapic *apic) | 458 | static u32 apic_get_tmcct(struct kvm_lapic *apic) |