diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 4727c08da2e9..8966fd13e848 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -192,16 +192,31 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm, | |||
192 | return -EINVAL; | 192 | return -EINVAL; |
193 | } | 193 | } |
194 | 194 | ||
195 | if (match->irq_requested) { | 195 | if (!match->irq_requested) { |
196 | INIT_WORK(&match->interrupt_work, | ||
197 | kvm_assigned_dev_interrupt_work_handler); | ||
198 | if (irqchip_in_kernel(kvm)) { | ||
199 | /* Register ack nofitier */ | ||
200 | match->ack_notifier.gsi = -1; | ||
201 | match->ack_notifier.irq_acked = | ||
202 | kvm_assigned_dev_ack_irq; | ||
203 | kvm_register_irq_ack_notifier(kvm, | ||
204 | &match->ack_notifier); | ||
205 | |||
206 | /* Request IRQ source ID */ | ||
207 | r = kvm_request_irq_source_id(kvm); | ||
208 | if (r < 0) | ||
209 | goto out_release; | ||
210 | else | ||
211 | match->irq_source_id = r; | ||
212 | } | ||
213 | } else { | ||
196 | match->guest_irq = assigned_irq->guest_irq; | 214 | match->guest_irq = assigned_irq->guest_irq; |
197 | match->ack_notifier.gsi = assigned_irq->guest_irq; | 215 | match->ack_notifier.gsi = assigned_irq->guest_irq; |
198 | mutex_unlock(&kvm->lock); | 216 | mutex_unlock(&kvm->lock); |
199 | return 0; | 217 | return 0; |
200 | } | 218 | } |
201 | 219 | ||
202 | INIT_WORK(&match->interrupt_work, | ||
203 | kvm_assigned_dev_interrupt_work_handler); | ||
204 | |||
205 | if (irqchip_in_kernel(kvm)) { | 220 | if (irqchip_in_kernel(kvm)) { |
206 | if (!capable(CAP_SYS_RAWIO)) { | 221 | if (!capable(CAP_SYS_RAWIO)) { |
207 | r = -EPERM; | 222 | r = -EPERM; |
@@ -214,13 +229,6 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm, | |||
214 | match->host_irq = match->dev->irq; | 229 | match->host_irq = match->dev->irq; |
215 | match->guest_irq = assigned_irq->guest_irq; | 230 | match->guest_irq = assigned_irq->guest_irq; |
216 | match->ack_notifier.gsi = assigned_irq->guest_irq; | 231 | match->ack_notifier.gsi = assigned_irq->guest_irq; |
217 | match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq; | ||
218 | kvm_register_irq_ack_notifier(kvm, &match->ack_notifier); | ||
219 | r = kvm_request_irq_source_id(kvm); | ||
220 | if (r < 0) | ||
221 | goto out_release; | ||
222 | else | ||
223 | match->irq_source_id = r; | ||
224 | 232 | ||
225 | /* Even though this is PCI, we don't want to use shared | 233 | /* Even though this is PCI, we don't want to use shared |
226 | * interrupts. Sharing host devices with guest-assigned devices | 234 | * interrupts. Sharing host devices with guest-assigned devices |