aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/eventfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/eventfd.c')
-rw-r--r--virt/kvm/eventfd.c251
1 files changed, 250 insertions, 1 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 4092b8dcd510..99017e8a92ac 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
24#include <linux/kvm.h>
24#include <linux/workqueue.h> 25#include <linux/workqueue.h>
25#include <linux/syscalls.h> 26#include <linux/syscalls.h>
26#include <linux/wait.h> 27#include <linux/wait.h>
@@ -28,6 +29,9 @@
28#include <linux/file.h> 29#include <linux/file.h>
29#include <linux/list.h> 30#include <linux/list.h>
30#include <linux/eventfd.h> 31#include <linux/eventfd.h>
32#include <linux/kernel.h>
33
34#include "iodev.h"
31 35
32/* 36/*
33 * -------------------------------------------------------------------- 37 * --------------------------------------------------------------------
@@ -234,10 +238,11 @@ fail:
234} 238}
235 239
236void 240void
237kvm_irqfd_init(struct kvm *kvm) 241kvm_eventfd_init(struct kvm *kvm)
238{ 242{
239 spin_lock_init(&kvm->irqfds.lock); 243 spin_lock_init(&kvm->irqfds.lock);
240 INIT_LIST_HEAD(&kvm->irqfds.items); 244 INIT_LIST_HEAD(&kvm->irqfds.items);
245 INIT_LIST_HEAD(&kvm->ioeventfds);
241} 246}
242 247
243/* 248/*
@@ -327,3 +332,247 @@ static void __exit irqfd_module_exit(void)
327 332
328module_init(irqfd_module_init); 333module_init(irqfd_module_init);
329module_exit(irqfd_module_exit); 334module_exit(irqfd_module_exit);
335
336/*
337 * --------------------------------------------------------------------
338 * ioeventfd: translate a PIO/MMIO memory write to an eventfd signal.
339 *
340 * userspace can register a PIO/MMIO address with an eventfd for receiving
341 * notification when the memory has been touched.
342 * --------------------------------------------------------------------
343 */
344
345struct _ioeventfd {
346 struct list_head list;
347 u64 addr;
348 int length;
349 struct eventfd_ctx *eventfd;
350 u64 datamatch;
351 struct kvm_io_device dev;
352 bool wildcard;
353};
354
355static inline struct _ioeventfd *
356to_ioeventfd(struct kvm_io_device *dev)
357{
358 return container_of(dev, struct _ioeventfd, dev);
359}
360
361static void
362ioeventfd_release(struct _ioeventfd *p)
363{
364 eventfd_ctx_put(p->eventfd);
365 list_del(&p->list);
366 kfree(p);
367}
368
369static bool
370ioeventfd_in_range(struct _ioeventfd *p, gpa_t addr, int len, const void *val)
371{
372 u64 _val;
373
374 if (!(addr == p->addr && len == p->length))
375 /* address-range must be precise for a hit */
376 return false;
377
378 if (p->wildcard)
379 /* all else equal, wildcard is always a hit */
380 return true;
381
382 /* otherwise, we have to actually compare the data */
383
384 BUG_ON(!IS_ALIGNED((unsigned long)val, len));
385
386 switch (len) {
387 case 1:
388 _val = *(u8 *)val;
389 break;
390 case 2:
391 _val = *(u16 *)val;
392 break;
393 case 4:
394 _val = *(u32 *)val;
395 break;
396 case 8:
397 _val = *(u64 *)val;
398 break;
399 default:
400 return false;
401 }
402
403 return _val == p->datamatch ? true : false;
404}
405
406/* MMIO/PIO writes trigger an event if the addr/val match */
407static int
408ioeventfd_write(struct kvm_io_device *this, gpa_t addr, int len,
409 const void *val)
410{
411 struct _ioeventfd *p = to_ioeventfd(this);
412
413 if (!ioeventfd_in_range(p, addr, len, val))
414 return -EOPNOTSUPP;
415
416 eventfd_signal(p->eventfd, 1);
417 return 0;
418}
419
420/*
421 * This function is called as KVM is completely shutting down. We do not
422 * need to worry about locking just nuke anything we have as quickly as possible
423 */
424static void
425ioeventfd_destructor(struct kvm_io_device *this)
426{
427 struct _ioeventfd *p = to_ioeventfd(this);
428
429 ioeventfd_release(p);
430}
431
432static const struct kvm_io_device_ops ioeventfd_ops = {
433 .write = ioeventfd_write,
434 .destructor = ioeventfd_destructor,
435};
436
437/* assumes kvm->slots_lock held */
438static bool
439ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
440{
441 struct _ioeventfd *_p;
442
443 list_for_each_entry(_p, &kvm->ioeventfds, list)
444 if (_p->addr == p->addr && _p->length == p->length &&
445 (_p->wildcard || p->wildcard ||
446 _p->datamatch == p->datamatch))
447 return true;
448
449 return false;
450}
451
452static int
453kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
454{
455 int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
456 struct kvm_io_bus *bus = pio ? &kvm->pio_bus : &kvm->mmio_bus;
457 struct _ioeventfd *p;
458 struct eventfd_ctx *eventfd;
459 int ret;
460
461 /* must be natural-word sized */
462 switch (args->len) {
463 case 1:
464 case 2:
465 case 4:
466 case 8:
467 break;
468 default:
469 return -EINVAL;
470 }
471
472 /* check for range overflow */
473 if (args->addr + args->len < args->addr)
474 return -EINVAL;
475
476 /* check for extra flags that we don't understand */
477 if (args->flags & ~KVM_IOEVENTFD_VALID_FLAG_MASK)
478 return -EINVAL;
479
480 eventfd = eventfd_ctx_fdget(args->fd);
481 if (IS_ERR(eventfd))
482 return PTR_ERR(eventfd);
483
484 p = kzalloc(sizeof(*p), GFP_KERNEL);
485 if (!p) {
486 ret = -ENOMEM;
487 goto fail;
488 }
489
490 INIT_LIST_HEAD(&p->list);
491 p->addr = args->addr;
492 p->length = args->len;
493 p->eventfd = eventfd;
494
495 /* The datamatch feature is optional, otherwise this is a wildcard */
496 if (args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH)
497 p->datamatch = args->datamatch;
498 else
499 p->wildcard = true;
500
501 down_write(&kvm->slots_lock);
502
503 /* Verify that there isnt a match already */
504 if (ioeventfd_check_collision(kvm, p)) {
505 ret = -EEXIST;
506 goto unlock_fail;
507 }
508
509 kvm_iodevice_init(&p->dev, &ioeventfd_ops);
510
511 ret = __kvm_io_bus_register_dev(bus, &p->dev);
512 if (ret < 0)
513 goto unlock_fail;
514
515 list_add_tail(&p->list, &kvm->ioeventfds);
516
517 up_write(&kvm->slots_lock);
518
519 return 0;
520
521unlock_fail:
522 up_write(&kvm->slots_lock);
523
524fail:
525 kfree(p);
526 eventfd_ctx_put(eventfd);
527
528 return ret;
529}
530
531static int
532kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
533{
534 int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
535 struct kvm_io_bus *bus = pio ? &kvm->pio_bus : &kvm->mmio_bus;
536 struct _ioeventfd *p, *tmp;
537 struct eventfd_ctx *eventfd;
538 int ret = -ENOENT;
539
540 eventfd = eventfd_ctx_fdget(args->fd);
541 if (IS_ERR(eventfd))
542 return PTR_ERR(eventfd);
543
544 down_write(&kvm->slots_lock);
545
546 list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) {
547 bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH);
548
549 if (p->eventfd != eventfd ||
550 p->addr != args->addr ||
551 p->length != args->len ||
552 p->wildcard != wildcard)
553 continue;
554
555 if (!p->wildcard && p->datamatch != args->datamatch)
556 continue;
557
558 __kvm_io_bus_unregister_dev(bus, &p->dev);
559 ioeventfd_release(p);
560 ret = 0;
561 break;
562 }
563
564 up_write(&kvm->slots_lock);
565
566 eventfd_ctx_put(eventfd);
567
568 return ret;
569}
570
571int
572kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
573{
574 if (args->flags & KVM_IOEVENTFD_FLAG_DEASSIGN)
575 return kvm_deassign_ioeventfd(kvm, args);
576
577 return kvm_assign_ioeventfd(kvm, args);
578}