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/ia64/kvm | |
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/ia64/kvm')
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 319922137fdd..8dde36953af3 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -1000,10 +1000,10 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1000 | goto out; | 1000 | goto out; |
1001 | if (irqchip_in_kernel(kvm)) { | 1001 | if (irqchip_in_kernel(kvm)) { |
1002 | __s32 status; | 1002 | __s32 status; |
1003 | mutex_lock(&kvm->lock); | 1003 | mutex_lock(&kvm->irq_lock); |
1004 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | 1004 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, |
1005 | irq_event.irq, irq_event.level); | 1005 | irq_event.irq, irq_event.level); |
1006 | mutex_unlock(&kvm->lock); | 1006 | mutex_unlock(&kvm->irq_lock); |
1007 | if (ioctl == KVM_IRQ_LINE_STATUS) { | 1007 | if (ioctl == KVM_IRQ_LINE_STATUS) { |
1008 | irq_event.status = status; | 1008 | irq_event.status = status; |
1009 | if (copy_to_user(argp, &irq_event, | 1009 | if (copy_to_user(argp, &irq_event, |