diff options
Diffstat (limited to 'virt/kvm')
-rw-r--r-- | virt/kvm/eventfd.c | 18 | ||||
-rw-r--r-- | virt/kvm/irq_comm.c | 6 |
2 files changed, 20 insertions, 4 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 30f70fd511c4..a9d3fc6c681c 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
@@ -72,12 +72,13 @@ static void | |||
72 | irqfd_shutdown(struct work_struct *work) | 72 | irqfd_shutdown(struct work_struct *work) |
73 | { | 73 | { |
74 | struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown); | 74 | struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown); |
75 | u64 cnt; | ||
75 | 76 | ||
76 | /* | 77 | /* |
77 | * Synchronize with the wait-queue and unhook ourselves to prevent | 78 | * Synchronize with the wait-queue and unhook ourselves to prevent |
78 | * further events. | 79 | * further events. |
79 | */ | 80 | */ |
80 | remove_wait_queue(irqfd->wqh, &irqfd->wait); | 81 | eventfd_ctx_remove_wait_queue(irqfd->eventfd, &irqfd->wait, &cnt); |
81 | 82 | ||
82 | /* | 83 | /* |
83 | * We know no new events will be scheduled at this point, so block | 84 | * We know no new events will be scheduled at this point, so block |
@@ -166,7 +167,7 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh, | |||
166 | static int | 167 | static int |
167 | kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) | 168 | kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) |
168 | { | 169 | { |
169 | struct _irqfd *irqfd; | 170 | struct _irqfd *irqfd, *tmp; |
170 | struct file *file = NULL; | 171 | struct file *file = NULL; |
171 | struct eventfd_ctx *eventfd = NULL; | 172 | struct eventfd_ctx *eventfd = NULL; |
172 | int ret; | 173 | int ret; |
@@ -203,9 +204,20 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) | |||
203 | init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup); | 204 | init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup); |
204 | init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc); | 205 | init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc); |
205 | 206 | ||
207 | spin_lock_irq(&kvm->irqfds.lock); | ||
208 | |||
209 | ret = 0; | ||
210 | list_for_each_entry(tmp, &kvm->irqfds.items, list) { | ||
211 | if (irqfd->eventfd != tmp->eventfd) | ||
212 | continue; | ||
213 | /* This fd is used for another irq already. */ | ||
214 | ret = -EBUSY; | ||
215 | spin_unlock_irq(&kvm->irqfds.lock); | ||
216 | goto fail; | ||
217 | } | ||
218 | |||
206 | events = file->f_op->poll(file, &irqfd->pt); | 219 | events = file->f_op->poll(file, &irqfd->pt); |
207 | 220 | ||
208 | spin_lock_irq(&kvm->irqfds.lock); | ||
209 | list_add_tail(&irqfd->list, &kvm->irqfds.items); | 221 | list_add_tail(&irqfd->list, &kvm->irqfds.items); |
210 | spin_unlock_irq(&kvm->irqfds.lock); | 222 | spin_unlock_irq(&kvm->irqfds.lock); |
211 | 223 | ||
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 9b077342ab54..9fd5b3ebc517 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -302,6 +302,7 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, | |||
302 | { | 302 | { |
303 | int r = -EINVAL; | 303 | int r = -EINVAL; |
304 | int delta; | 304 | int delta; |
305 | unsigned max_pin; | ||
305 | struct kvm_kernel_irq_routing_entry *ei; | 306 | struct kvm_kernel_irq_routing_entry *ei; |
306 | struct hlist_node *n; | 307 | struct hlist_node *n; |
307 | 308 | ||
@@ -322,12 +323,15 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, | |||
322 | switch (ue->u.irqchip.irqchip) { | 323 | switch (ue->u.irqchip.irqchip) { |
323 | case KVM_IRQCHIP_PIC_MASTER: | 324 | case KVM_IRQCHIP_PIC_MASTER: |
324 | e->set = kvm_set_pic_irq; | 325 | e->set = kvm_set_pic_irq; |
326 | max_pin = 16; | ||
325 | break; | 327 | break; |
326 | case KVM_IRQCHIP_PIC_SLAVE: | 328 | case KVM_IRQCHIP_PIC_SLAVE: |
327 | e->set = kvm_set_pic_irq; | 329 | e->set = kvm_set_pic_irq; |
330 | max_pin = 16; | ||
328 | delta = 8; | 331 | delta = 8; |
329 | break; | 332 | break; |
330 | case KVM_IRQCHIP_IOAPIC: | 333 | case KVM_IRQCHIP_IOAPIC: |
334 | max_pin = KVM_IOAPIC_NUM_PINS; | ||
331 | e->set = kvm_set_ioapic_irq; | 335 | e->set = kvm_set_ioapic_irq; |
332 | break; | 336 | break; |
333 | default: | 337 | default: |
@@ -335,7 +339,7 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, | |||
335 | } | 339 | } |
336 | e->irqchip.irqchip = ue->u.irqchip.irqchip; | 340 | e->irqchip.irqchip = ue->u.irqchip.irqchip; |
337 | e->irqchip.pin = ue->u.irqchip.pin + delta; | 341 | e->irqchip.pin = ue->u.irqchip.pin + delta; |
338 | if (e->irqchip.pin >= KVM_IOAPIC_NUM_PINS) | 342 | if (e->irqchip.pin >= max_pin) |
339 | goto out; | 343 | goto out; |
340 | rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi; | 344 | rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi; |
341 | break; | 345 | break; |