diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d47e660fb709..0d481b282448 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -62,6 +62,12 @@ | |||
62 | MODULE_AUTHOR("Qumranet"); | 62 | MODULE_AUTHOR("Qumranet"); |
63 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
64 | 64 | ||
65 | /* | ||
66 | * Ordering of locks: | ||
67 | * | ||
68 | * kvm->lock --> kvm->irq_lock | ||
69 | */ | ||
70 | |||
65 | DEFINE_SPINLOCK(kvm_lock); | 71 | DEFINE_SPINLOCK(kvm_lock); |
66 | LIST_HEAD(vm_list); | 72 | LIST_HEAD(vm_list); |
67 | 73 | ||
@@ -126,11 +132,7 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) | |||
126 | interrupt_work); | 132 | interrupt_work); |
127 | kvm = assigned_dev->kvm; | 133 | kvm = assigned_dev->kvm; |
128 | 134 | ||
129 | /* This is taken to safely inject irq inside the guest. When | 135 | mutex_lock(&kvm->irq_lock); |
130 | * the interrupt injection (or the ioapic code) uses a | ||
131 | * finer-grained lock, update this | ||
132 | */ | ||
133 | mutex_lock(&kvm->lock); | ||
134 | spin_lock_irq(&assigned_dev->assigned_dev_lock); | 136 | spin_lock_irq(&assigned_dev->assigned_dev_lock); |
135 | if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) { | 137 | if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) { |
136 | struct kvm_guest_msix_entry *guest_entries = | 138 | struct kvm_guest_msix_entry *guest_entries = |
@@ -149,7 +151,7 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) | |||
149 | assigned_dev->guest_irq, 1); | 151 | assigned_dev->guest_irq, 1); |
150 | 152 | ||
151 | spin_unlock_irq(&assigned_dev->assigned_dev_lock); | 153 | spin_unlock_irq(&assigned_dev->assigned_dev_lock); |
152 | mutex_unlock(&assigned_dev->kvm->lock); | 154 | mutex_unlock(&assigned_dev->kvm->irq_lock); |
153 | } | 155 | } |
154 | 156 | ||
155 | static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) | 157 | static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) |
@@ -207,7 +209,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) | |||
207 | static void deassign_guest_irq(struct kvm *kvm, | 209 | static void deassign_guest_irq(struct kvm *kvm, |
208 | struct kvm_assigned_dev_kernel *assigned_dev) | 210 | struct kvm_assigned_dev_kernel *assigned_dev) |
209 | { | 211 | { |
210 | kvm_unregister_irq_ack_notifier(&assigned_dev->ack_notifier); | 212 | kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier); |
211 | assigned_dev->ack_notifier.gsi = -1; | 213 | assigned_dev->ack_notifier.gsi = -1; |
212 | 214 | ||
213 | if (assigned_dev->irq_source_id != -1) | 215 | if (assigned_dev->irq_source_id != -1) |