Commit f1d1c309f35e9b0fb961cffd70fbd04f450ec47c
Committed by
Marcelo Tosatti
1 parent
82b7005f0e
Exists in
master
and in
7 other branches
KVM: only allow one gsi per fd
Looks like repeatedly binding same fd to multiple gsi's with irqfd can use up a ton of kernel memory for irqfd structures. A simple fix is to allow each fd to only trigger one gsi: triggering a storm of interrupts in guest is likely useless anyway, and we can do it by binding a single gsi to many interrupts if we really want to. Cc: stable@kernel.org Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Acked-by: Gregory Haskins <ghaskins@novell.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Showing 1 changed file with 13 additions and 2 deletions Side-by-side Diff
virt/kvm/eventfd.c
... | ... | @@ -166,7 +166,7 @@ |
166 | 166 | static int |
167 | 167 | kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) |
168 | 168 | { |
169 | - struct _irqfd *irqfd; | |
169 | + struct _irqfd *irqfd, *tmp; | |
170 | 170 | struct file *file = NULL; |
171 | 171 | struct eventfd_ctx *eventfd = NULL; |
172 | 172 | int ret; |
173 | 173 | |
... | ... | @@ -203,9 +203,20 @@ |
203 | 203 | init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup); |
204 | 204 | init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc); |
205 | 205 | |
206 | + spin_lock_irq(&kvm->irqfds.lock); | |
207 | + | |
208 | + ret = 0; | |
209 | + list_for_each_entry(tmp, &kvm->irqfds.items, list) { | |
210 | + if (irqfd->eventfd != tmp->eventfd) | |
211 | + continue; | |
212 | + /* This fd is used for another irq already. */ | |
213 | + ret = -EBUSY; | |
214 | + spin_unlock_irq(&kvm->irqfds.lock); | |
215 | + goto fail; | |
216 | + } | |
217 | + | |
206 | 218 | events = file->f_op->poll(file, &irqfd->pt); |
207 | 219 | |
208 | - spin_lock_irq(&kvm->irqfds.lock); | |
209 | 220 | list_add_tail(&irqfd->list, &kvm->irqfds.items); |
210 | 221 | spin_unlock_irq(&kvm->irqfds.lock); |
211 | 222 |