aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/eventfd.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2010-02-26 19:04:15 +0000
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-02-26 19:06:24 +0000
commita7790532f5b7358c33a6b1834dc2b318de209f31 (patch)
tree0ceb9e24b3f54cb5c8453fb5a218e2a94a0f1cce /virt/kvm/eventfd.c
parent2764fb4244cc1bc08df3667924ca4a972e90ac70 (diff)
parent60b341b778cc2929df16c0a504c91621b3c6a4ad (diff)
downloadkernel_samsung_smdk4412-a7790532f5b7358c33a6b1834dc2b318de209f31.zip
kernel_samsung_smdk4412-a7790532f5b7358c33a6b1834dc2b318de209f31.tar.gz
kernel_samsung_smdk4412-a7790532f5b7358c33a6b1834dc2b318de209f31.tar.bz2
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
The SmartMedia FTL code depends on new kfifo bits from 2.6.33
Diffstat (limited to 'virt/kvm/eventfd.c')
-rw-r--r--virt/kvm/eventfd.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 30f70fd..a9d3fc6 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -72,12 +72,13 @@ static void
irqfd_shutdown(struct work_struct *work)
{
struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown);
+ u64 cnt;
/*
* Synchronize with the wait-queue and unhook ourselves to prevent
* further events.
*/
- remove_wait_queue(irqfd->wqh, &irqfd->wait);
+ eventfd_ctx_remove_wait_queue(irqfd->eventfd, &irqfd->wait, &cnt);
/*
* 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,
static int
kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
{
- struct _irqfd *irqfd;
+ struct _irqfd *irqfd, *tmp;
struct file *file = NULL;
struct eventfd_ctx *eventfd = NULL;
int ret;
@@ -203,9 +204,20 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup);
init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc);
+ spin_lock_irq(&kvm->irqfds.lock);
+
+ ret = 0;
+ list_for_each_entry(tmp, &kvm->irqfds.items, list) {
+ if (irqfd->eventfd != tmp->eventfd)
+ continue;
+ /* This fd is used for another irq already. */
+ ret = -EBUSY;
+ spin_unlock_irq(&kvm->irqfds.lock);
+ goto fail;
+ }
+
events = file->f_op->poll(file, &irqfd->pt);
- spin_lock_irq(&kvm->irqfds.lock);
list_add_tail(&irqfd->list, &kvm->irqfds.items);
spin_unlock_irq(&kvm->irqfds.lock);