Blame view

virt/kvm/eventfd.c 15.3 KB
721eecbf4   Gregory Haskins   KVM: irqfd
1
2
3
4
  /*
   * kvm eventfd support - use eventfd objects to signal various KVM events
   *
   * Copyright 2009 Novell.  All Rights Reserved.
221d059d1   Avi Kivity   KVM: Update Red H...
5
   * Copyright 2010 Red Hat, Inc. and/or its affiliates.
721eecbf4   Gregory Haskins   KVM: irqfd
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   *
   * Author:
   *	Gregory Haskins <ghaskins@novell.com>
   *
   * This file is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License
   * as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
   */
  
  #include <linux/kvm_host.h>
d34e6b175   Gregory Haskins   KVM: add ioeventf...
25
  #include <linux/kvm.h>
721eecbf4   Gregory Haskins   KVM: irqfd
26
27
28
29
30
31
32
  #include <linux/workqueue.h>
  #include <linux/syscalls.h>
  #include <linux/wait.h>
  #include <linux/poll.h>
  #include <linux/file.h>
  #include <linux/list.h>
  #include <linux/eventfd.h>
d34e6b175   Gregory Haskins   KVM: add ioeventf...
33
  #include <linux/kernel.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
34
  #include <linux/slab.h>
d34e6b175   Gregory Haskins   KVM: add ioeventf...
35
36
  
  #include "iodev.h"
721eecbf4   Gregory Haskins   KVM: irqfd
37
38
39
40
41
42
43
44
45
46
  
  /*
   * --------------------------------------------------------------------
   * irqfd: Allows an fd to be used to inject an interrupt to the guest
   *
   * Credit goes to Avi Kivity for the original idea.
   * --------------------------------------------------------------------
   */
  
  struct _irqfd {
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
47
48
49
50
51
52
53
54
55
56
57
58
59
  	/* Used for MSI fast-path */
  	struct kvm *kvm;
  	wait_queue_t wait;
  	/* Update side is protected by irqfds.lock */
  	struct kvm_kernel_irq_routing_entry __rcu *irq_entry;
  	/* Used for level IRQ fast-path */
  	int gsi;
  	struct work_struct inject;
  	/* Used for setup/shutdown */
  	struct eventfd_ctx *eventfd;
  	struct list_head list;
  	poll_table pt;
  	struct work_struct shutdown;
721eecbf4   Gregory Haskins   KVM: irqfd
60
61
62
63
64
65
66
67
68
  };
  
  static struct workqueue_struct *irqfd_cleanup_wq;
  
  static void
  irqfd_inject(struct work_struct *work)
  {
  	struct _irqfd *irqfd = container_of(work, struct _irqfd, inject);
  	struct kvm *kvm = irqfd->kvm;
721eecbf4   Gregory Haskins   KVM: irqfd
69
70
  	kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1);
  	kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0);
721eecbf4   Gregory Haskins   KVM: irqfd
71
72
73
74
75
76
77
78
79
  }
  
  /*
   * Race-free decouple logic (ordering is critical)
   */
  static void
  irqfd_shutdown(struct work_struct *work)
  {
  	struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown);
b6a114d27   Michael S. Tsirkin   KVM: fix spurious...
80
  	u64 cnt;
721eecbf4   Gregory Haskins   KVM: irqfd
81
82
83
84
85
  
  	/*
  	 * Synchronize with the wait-queue and unhook ourselves to prevent
  	 * further events.
  	 */
b6a114d27   Michael S. Tsirkin   KVM: fix spurious...
86
  	eventfd_ctx_remove_wait_queue(irqfd->eventfd, &irqfd->wait, &cnt);
721eecbf4   Gregory Haskins   KVM: irqfd
87
88
89
90
91
  
  	/*
  	 * We know no new events will be scheduled at this point, so block
  	 * until all previously outstanding events have completed
  	 */
9e02fb963   Michael S. Tsirkin   KVM: fix crash on...
92
  	flush_work_sync(&irqfd->inject);
721eecbf4   Gregory Haskins   KVM: irqfd
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  
  	/*
  	 * It is now safe to release the object's resources
  	 */
  	eventfd_ctx_put(irqfd->eventfd);
  	kfree(irqfd);
  }
  
  
  /* assumes kvm->irqfds.lock is held */
  static bool
  irqfd_is_active(struct _irqfd *irqfd)
  {
  	return list_empty(&irqfd->list) ? false : true;
  }
  
  /*
   * Mark the irqfd as inactive and schedule it for removal
   *
   * assumes kvm->irqfds.lock is held
   */
  static void
  irqfd_deactivate(struct _irqfd *irqfd)
  {
  	BUG_ON(!irqfd_is_active(irqfd));
  
  	list_del_init(&irqfd->list);
  
  	queue_work(irqfd_cleanup_wq, &irqfd->shutdown);
  }
  
  /*
   * Called with wqh->lock held and interrupts disabled
   */
  static int
  irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
  {
  	struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait);
  	unsigned long flags = (unsigned long)key;
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
132
133
  	struct kvm_kernel_irq_routing_entry *irq;
  	struct kvm *kvm = irqfd->kvm;
721eecbf4   Gregory Haskins   KVM: irqfd
134

bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
135
136
137
  	if (flags & POLLIN) {
  		rcu_read_lock();
  		irq = rcu_dereference(irqfd->irq_entry);
721eecbf4   Gregory Haskins   KVM: irqfd
138
  		/* An event has been signaled, inject an interrupt */
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
139
140
141
142
143
144
  		if (irq)
  			kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1);
  		else
  			schedule_work(&irqfd->inject);
  		rcu_read_unlock();
  	}
721eecbf4   Gregory Haskins   KVM: irqfd
145
146
147
  
  	if (flags & POLLHUP) {
  		/* The eventfd is closing, detach from KVM */
721eecbf4   Gregory Haskins   KVM: irqfd
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
  		unsigned long flags;
  
  		spin_lock_irqsave(&kvm->irqfds.lock, flags);
  
  		/*
  		 * We must check if someone deactivated the irqfd before
  		 * we could acquire the irqfds.lock since the item is
  		 * deactivated from the KVM side before it is unhooked from
  		 * the wait-queue.  If it is already deactivated, we can
  		 * simply return knowing the other side will cleanup for us.
  		 * We cannot race against the irqfd going away since the
  		 * other side is required to acquire wqh->lock, which we hold
  		 */
  		if (irqfd_is_active(irqfd))
  			irqfd_deactivate(irqfd);
  
  		spin_unlock_irqrestore(&kvm->irqfds.lock, flags);
  	}
  
  	return 0;
  }
  
  static void
  irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
  			poll_table *pt)
  {
  	struct _irqfd *irqfd = container_of(pt, struct _irqfd, pt);
721eecbf4   Gregory Haskins   KVM: irqfd
175
176
  	add_wait_queue(wqh, &irqfd->wait);
  }
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  /* Must be called under irqfds.lock */
  static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
  			 struct kvm_irq_routing_table *irq_rt)
  {
  	struct kvm_kernel_irq_routing_entry *e;
  	struct hlist_node *n;
  
  	if (irqfd->gsi >= irq_rt->nr_rt_entries) {
  		rcu_assign_pointer(irqfd->irq_entry, NULL);
  		return;
  	}
  
  	hlist_for_each_entry(e, n, &irq_rt->map[irqfd->gsi], link) {
  		/* Only fast-path MSI. */
  		if (e->type == KVM_IRQ_ROUTING_MSI)
  			rcu_assign_pointer(irqfd->irq_entry, e);
  		else
  			rcu_assign_pointer(irqfd->irq_entry, NULL);
  	}
  }
721eecbf4   Gregory Haskins   KVM: irqfd
197
198
199
  static int
  kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
  {
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
200
  	struct kvm_irq_routing_table *irq_rt;
f1d1c309f   Michael S. Tsirkin   KVM: only allow o...
201
  	struct _irqfd *irqfd, *tmp;
721eecbf4   Gregory Haskins   KVM: irqfd
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  	struct file *file = NULL;
  	struct eventfd_ctx *eventfd = NULL;
  	int ret;
  	unsigned int events;
  
  	irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
  	if (!irqfd)
  		return -ENOMEM;
  
  	irqfd->kvm = kvm;
  	irqfd->gsi = gsi;
  	INIT_LIST_HEAD(&irqfd->list);
  	INIT_WORK(&irqfd->inject, irqfd_inject);
  	INIT_WORK(&irqfd->shutdown, irqfd_shutdown);
  
  	file = eventfd_fget(fd);
  	if (IS_ERR(file)) {
  		ret = PTR_ERR(file);
  		goto fail;
  	}
  
  	eventfd = eventfd_ctx_fileget(file);
  	if (IS_ERR(eventfd)) {
  		ret = PTR_ERR(eventfd);
  		goto fail;
  	}
  
  	irqfd->eventfd = eventfd;
  
  	/*
  	 * Install our own custom wake-up handling so we are notified via
  	 * a callback whenever someone signals the underlying eventfd
  	 */
  	init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup);
  	init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc);
f1d1c309f   Michael S. Tsirkin   KVM: only allow o...
237
238
239
240
241
242
243
244
245
246
247
  	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;
  	}
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
248
249
250
  	irq_rt = rcu_dereference_protected(kvm->irq_routing,
  					   lockdep_is_held(&kvm->irqfds.lock));
  	irqfd_update(kvm, irqfd, irq_rt);
721eecbf4   Gregory Haskins   KVM: irqfd
251
  	events = file->f_op->poll(file, &irqfd->pt);
721eecbf4   Gregory Haskins   KVM: irqfd
252
  	list_add_tail(&irqfd->list, &kvm->irqfds.items);
721eecbf4   Gregory Haskins   KVM: irqfd
253
254
255
256
257
258
259
  
  	/*
  	 * Check if there was an event already pending on the eventfd
  	 * before we registered, and trigger it as if we didn't miss it.
  	 */
  	if (events & POLLIN)
  		schedule_work(&irqfd->inject);
6bbfb2653   Michael S. Tsirkin   KVM: fix irqfd as...
260
  	spin_unlock_irq(&kvm->irqfds.lock);
721eecbf4   Gregory Haskins   KVM: irqfd
261
262
263
264
265
266
267
268
269
270
271
  	/*
  	 * do not drop the file until the irqfd is fully initialized, otherwise
  	 * we might race against the POLLHUP
  	 */
  	fput(file);
  
  	return 0;
  
  fail:
  	if (eventfd && !IS_ERR(eventfd))
  		eventfd_ctx_put(eventfd);
6223011fb   Julia Lawall   KVM: correct erro...
272
  	if (!IS_ERR(file))
721eecbf4   Gregory Haskins   KVM: irqfd
273
274
275
276
277
278
279
  		fput(file);
  
  	kfree(irqfd);
  	return ret;
  }
  
  void
d34e6b175   Gregory Haskins   KVM: add ioeventf...
280
  kvm_eventfd_init(struct kvm *kvm)
721eecbf4   Gregory Haskins   KVM: irqfd
281
282
283
  {
  	spin_lock_init(&kvm->irqfds.lock);
  	INIT_LIST_HEAD(&kvm->irqfds.items);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
284
  	INIT_LIST_HEAD(&kvm->ioeventfds);
721eecbf4   Gregory Haskins   KVM: irqfd
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  }
  
  /*
   * shutdown any irqfd's that match fd+gsi
   */
  static int
  kvm_irqfd_deassign(struct kvm *kvm, int fd, int gsi)
  {
  	struct _irqfd *irqfd, *tmp;
  	struct eventfd_ctx *eventfd;
  
  	eventfd = eventfd_ctx_fdget(fd);
  	if (IS_ERR(eventfd))
  		return PTR_ERR(eventfd);
  
  	spin_lock_irq(&kvm->irqfds.lock);
  
  	list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) {
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
303
304
305
  		if (irqfd->eventfd == eventfd && irqfd->gsi == gsi) {
  			/*
  			 * This rcu_assign_pointer is needed for when
c8ce057ea   Michael S. Tsirkin   KVM: improve comm...
306
307
308
  			 * another thread calls kvm_irq_routing_update before
  			 * we flush workqueue below (we synchronize with
  			 * kvm_irq_routing_update using irqfds.lock).
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
309
310
311
312
  			 * It is paired with synchronize_rcu done by caller
  			 * of that function.
  			 */
  			rcu_assign_pointer(irqfd->irq_entry, NULL);
721eecbf4   Gregory Haskins   KVM: irqfd
313
  			irqfd_deactivate(irqfd);
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
314
  		}
721eecbf4   Gregory Haskins   KVM: irqfd
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
  	}
  
  	spin_unlock_irq(&kvm->irqfds.lock);
  	eventfd_ctx_put(eventfd);
  
  	/*
  	 * Block until we know all outstanding shutdown jobs have completed
  	 * so that we guarantee there will not be any more interrupts on this
  	 * gsi once this deassign function returns.
  	 */
  	flush_workqueue(irqfd_cleanup_wq);
  
  	return 0;
  }
  
  int
  kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags)
  {
  	if (flags & KVM_IRQFD_FLAG_DEASSIGN)
  		return kvm_irqfd_deassign(kvm, fd, gsi);
  
  	return kvm_irqfd_assign(kvm, fd, gsi);
  }
  
  /*
   * This function is called as the kvm VM fd is being released. Shutdown all
   * irqfds that still remain open
   */
  void
  kvm_irqfd_release(struct kvm *kvm)
  {
  	struct _irqfd *irqfd, *tmp;
  
  	spin_lock_irq(&kvm->irqfds.lock);
  
  	list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list)
  		irqfd_deactivate(irqfd);
  
  	spin_unlock_irq(&kvm->irqfds.lock);
  
  	/*
  	 * Block until we know all outstanding shutdown jobs have completed
  	 * since we do not take a kvm* reference.
  	 */
  	flush_workqueue(irqfd_cleanup_wq);
  
  }
  
  /*
bd2b53b20   Michael S. Tsirkin   KVM: fast-path ms...
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
   * Change irq_routing and irqfd.
   * Caller must invoke synchronize_rcu afterwards.
   */
  void kvm_irq_routing_update(struct kvm *kvm,
  			    struct kvm_irq_routing_table *irq_rt)
  {
  	struct _irqfd *irqfd;
  
  	spin_lock_irq(&kvm->irqfds.lock);
  
  	rcu_assign_pointer(kvm->irq_routing, irq_rt);
  
  	list_for_each_entry(irqfd, &kvm->irqfds.items, list)
  		irqfd_update(kvm, irqfd, irq_rt);
  
  	spin_unlock_irq(&kvm->irqfds.lock);
  }
  
  /*
721eecbf4   Gregory Haskins   KVM: irqfd
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
   * create a host-wide workqueue for issuing deferred shutdown requests
   * aggregated from all vm* instances. We need our own isolated single-thread
   * queue to prevent deadlock against flushing the normal work-queue.
   */
  static int __init irqfd_module_init(void)
  {
  	irqfd_cleanup_wq = create_singlethread_workqueue("kvm-irqfd-cleanup");
  	if (!irqfd_cleanup_wq)
  		return -ENOMEM;
  
  	return 0;
  }
  
  static void __exit irqfd_module_exit(void)
  {
  	destroy_workqueue(irqfd_cleanup_wq);
  }
  
  module_init(irqfd_module_init);
  module_exit(irqfd_module_exit);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
  
  /*
   * --------------------------------------------------------------------
   * ioeventfd: translate a PIO/MMIO memory write to an eventfd signal.
   *
   * userspace can register a PIO/MMIO address with an eventfd for receiving
   * notification when the memory has been touched.
   * --------------------------------------------------------------------
   */
  
  struct _ioeventfd {
  	struct list_head     list;
  	u64                  addr;
  	int                  length;
  	struct eventfd_ctx  *eventfd;
  	u64                  datamatch;
  	struct kvm_io_device dev;
  	bool                 wildcard;
  };
  
  static inline struct _ioeventfd *
  to_ioeventfd(struct kvm_io_device *dev)
  {
  	return container_of(dev, struct _ioeventfd, dev);
  }
  
  static void
  ioeventfd_release(struct _ioeventfd *p)
  {
  	eventfd_ctx_put(p->eventfd);
  	list_del(&p->list);
  	kfree(p);
  }
  
  static bool
  ioeventfd_in_range(struct _ioeventfd *p, gpa_t addr, int len, const void *val)
  {
  	u64 _val;
  
  	if (!(addr == p->addr && len == p->length))
  		/* address-range must be precise for a hit */
  		return false;
  
  	if (p->wildcard)
  		/* all else equal, wildcard is always a hit */
  		return true;
  
  	/* otherwise, we have to actually compare the data */
  
  	BUG_ON(!IS_ALIGNED((unsigned long)val, len));
  
  	switch (len) {
  	case 1:
  		_val = *(u8 *)val;
  		break;
  	case 2:
  		_val = *(u16 *)val;
  		break;
  	case 4:
  		_val = *(u32 *)val;
  		break;
  	case 8:
  		_val = *(u64 *)val;
  		break;
  	default:
  		return false;
  	}
  
  	return _val == p->datamatch ? true : false;
  }
  
  /* MMIO/PIO writes trigger an event if the addr/val match */
  static int
  ioeventfd_write(struct kvm_io_device *this, gpa_t addr, int len,
  		const void *val)
  {
  	struct _ioeventfd *p = to_ioeventfd(this);
  
  	if (!ioeventfd_in_range(p, addr, len, val))
  		return -EOPNOTSUPP;
  
  	eventfd_signal(p->eventfd, 1);
  	return 0;
  }
  
  /*
   * This function is called as KVM is completely shutting down.  We do not
   * need to worry about locking just nuke anything we have as quickly as possible
   */
  static void
  ioeventfd_destructor(struct kvm_io_device *this)
  {
  	struct _ioeventfd *p = to_ioeventfd(this);
  
  	ioeventfd_release(p);
  }
  
  static const struct kvm_io_device_ops ioeventfd_ops = {
  	.write      = ioeventfd_write,
  	.destructor = ioeventfd_destructor,
  };
  
  /* assumes kvm->slots_lock held */
  static bool
  ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
  {
  	struct _ioeventfd *_p;
  
  	list_for_each_entry(_p, &kvm->ioeventfds, list)
  		if (_p->addr == p->addr && _p->length == p->length &&
  		    (_p->wildcard || p->wildcard ||
  		     _p->datamatch == p->datamatch))
  			return true;
  
  	return false;
  }
  
  static int
  kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
  {
  	int                       pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
524
  	enum kvm_bus              bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
d34e6b175   Gregory Haskins   KVM: add ioeventf...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
  	struct _ioeventfd        *p;
  	struct eventfd_ctx       *eventfd;
  	int                       ret;
  
  	/* must be natural-word sized */
  	switch (args->len) {
  	case 1:
  	case 2:
  	case 4:
  	case 8:
  		break;
  	default:
  		return -EINVAL;
  	}
  
  	/* check for range overflow */
  	if (args->addr + args->len < args->addr)
  		return -EINVAL;
  
  	/* check for extra flags that we don't understand */
  	if (args->flags & ~KVM_IOEVENTFD_VALID_FLAG_MASK)
  		return -EINVAL;
  
  	eventfd = eventfd_ctx_fdget(args->fd);
  	if (IS_ERR(eventfd))
  		return PTR_ERR(eventfd);
  
  	p = kzalloc(sizeof(*p), GFP_KERNEL);
  	if (!p) {
  		ret = -ENOMEM;
  		goto fail;
  	}
  
  	INIT_LIST_HEAD(&p->list);
  	p->addr    = args->addr;
  	p->length  = args->len;
  	p->eventfd = eventfd;
  
  	/* The datamatch feature is optional, otherwise this is a wildcard */
  	if (args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH)
  		p->datamatch = args->datamatch;
  	else
  		p->wildcard = true;
79fac95ec   Marcelo Tosatti   KVM: convert slot...
568
  	mutex_lock(&kvm->slots_lock);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
569

25985edce   Lucas De Marchi   Fix common misspe...
570
  	/* Verify that there isn't a match already */
d34e6b175   Gregory Haskins   KVM: add ioeventf...
571
572
573
574
575
576
  	if (ioeventfd_check_collision(kvm, p)) {
  		ret = -EEXIST;
  		goto unlock_fail;
  	}
  
  	kvm_iodevice_init(&p->dev, &ioeventfd_ops);
743eeb0b0   Sasha Levin   KVM: Intelligent ...
577
578
  	ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
  				      &p->dev);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
579
580
581
582
  	if (ret < 0)
  		goto unlock_fail;
  
  	list_add_tail(&p->list, &kvm->ioeventfds);
79fac95ec   Marcelo Tosatti   KVM: convert slot...
583
  	mutex_unlock(&kvm->slots_lock);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
584
585
586
587
  
  	return 0;
  
  unlock_fail:
79fac95ec   Marcelo Tosatti   KVM: convert slot...
588
  	mutex_unlock(&kvm->slots_lock);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
589
590
591
592
593
594
595
596
597
598
599
600
  
  fail:
  	kfree(p);
  	eventfd_ctx_put(eventfd);
  
  	return ret;
  }
  
  static int
  kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
  {
  	int                       pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
601
  	enum kvm_bus              bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
d34e6b175   Gregory Haskins   KVM: add ioeventf...
602
603
604
605
606
607
608
  	struct _ioeventfd        *p, *tmp;
  	struct eventfd_ctx       *eventfd;
  	int                       ret = -ENOENT;
  
  	eventfd = eventfd_ctx_fdget(args->fd);
  	if (IS_ERR(eventfd))
  		return PTR_ERR(eventfd);
79fac95ec   Marcelo Tosatti   KVM: convert slot...
609
  	mutex_lock(&kvm->slots_lock);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
610
611
612
613
614
615
616
617
618
619
620
621
  
  	list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) {
  		bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH);
  
  		if (p->eventfd != eventfd  ||
  		    p->addr != args->addr  ||
  		    p->length != args->len ||
  		    p->wildcard != wildcard)
  			continue;
  
  		if (!p->wildcard && p->datamatch != args->datamatch)
  			continue;
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
622
  		kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
623
624
625
626
  		ioeventfd_release(p);
  		ret = 0;
  		break;
  	}
79fac95ec   Marcelo Tosatti   KVM: convert slot...
627
  	mutex_unlock(&kvm->slots_lock);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
628
629
630
631
632
633
634
635
636
637
638
639
640
641
  
  	eventfd_ctx_put(eventfd);
  
  	return ret;
  }
  
  int
  kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
  {
  	if (args->flags & KVM_IOEVENTFD_FLAG_DEASSIGN)
  		return kvm_deassign_ioeventfd(kvm, args);
  
  	return kvm_assign_ioeventfd(kvm, args);
  }