diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2013-02-28 06:33:20 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2013-03-05 17:12:17 -0500 |
commit | 2b83451b45d720ca38c03878ce42ff9139cad9e3 (patch) | |
tree | 374b4ab82ffc115dc8cb76f783f7735521b6c7bf | |
parent | 060f0ce6ff975decd1e0ee318c08e228bccbee1e (diff) |
KVM: ioeventfd for virtio-ccw devices.
Enhance KVM_IOEVENTFD with a new flag that allows to attach to virtio-ccw
devices on s390 via the KVM_VIRTIO_CCW_NOTIFY_BUS.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 8 | ||||
-rw-r--r-- | include/uapi/linux/kvm.h | 3 | ||||
-rw-r--r-- | virt/kvm/eventfd.c | 17 |
3 files changed, 24 insertions, 4 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 119358dfb742..c16b442556e8 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -1486,15 +1486,23 @@ struct kvm_ioeventfd { | |||
1486 | __u8 pad[36]; | 1486 | __u8 pad[36]; |
1487 | }; | 1487 | }; |
1488 | 1488 | ||
1489 | For the special case of virtio-ccw devices on s390, the ioevent is matched | ||
1490 | to a subchannel/virtqueue tuple instead. | ||
1491 | |||
1489 | The following flags are defined: | 1492 | The following flags are defined: |
1490 | 1493 | ||
1491 | #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) | 1494 | #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) |
1492 | #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) | 1495 | #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) |
1493 | #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) | 1496 | #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) |
1497 | #define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ | ||
1498 | (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) | ||
1494 | 1499 | ||
1495 | If datamatch flag is set, the event will be signaled only if the written value | 1500 | If datamatch flag is set, the event will be signaled only if the written value |
1496 | to the registered address is equal to datamatch in struct kvm_ioeventfd. | 1501 | to the registered address is equal to datamatch in struct kvm_ioeventfd. |
1497 | 1502 | ||
1503 | For virtio-ccw devices, addr contains the subchannel id and datamatch the | ||
1504 | virtqueue index. | ||
1505 | |||
1498 | 1506 | ||
1499 | 4.60 KVM_DIRTY_TLB | 1507 | 4.60 KVM_DIRTY_TLB |
1500 | 1508 | ||
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 3c56ba3d80c1..74d0ff3dfd66 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h | |||
@@ -449,12 +449,15 @@ enum { | |||
449 | kvm_ioeventfd_flag_nr_datamatch, | 449 | kvm_ioeventfd_flag_nr_datamatch, |
450 | kvm_ioeventfd_flag_nr_pio, | 450 | kvm_ioeventfd_flag_nr_pio, |
451 | kvm_ioeventfd_flag_nr_deassign, | 451 | kvm_ioeventfd_flag_nr_deassign, |
452 | kvm_ioeventfd_flag_nr_virtio_ccw_notify, | ||
452 | kvm_ioeventfd_flag_nr_max, | 453 | kvm_ioeventfd_flag_nr_max, |
453 | }; | 454 | }; |
454 | 455 | ||
455 | #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) | 456 | #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) |
456 | #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) | 457 | #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) |
457 | #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) | 458 | #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) |
459 | #define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ | ||
460 | (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) | ||
458 | 461 | ||
459 | #define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1) | 462 | #define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1) |
460 | 463 | ||
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 0b6fe69bb03d..020522ed9094 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
@@ -674,15 +674,24 @@ ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p) | |||
674 | return false; | 674 | return false; |
675 | } | 675 | } |
676 | 676 | ||
677 | static enum kvm_bus ioeventfd_bus_from_flags(__u32 flags) | ||
678 | { | ||
679 | if (flags & KVM_IOEVENTFD_FLAG_PIO) | ||
680 | return KVM_PIO_BUS; | ||
681 | if (flags & KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY) | ||
682 | return KVM_VIRTIO_CCW_NOTIFY_BUS; | ||
683 | return KVM_MMIO_BUS; | ||
684 | } | ||
685 | |||
677 | static int | 686 | static int |
678 | kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) | 687 | kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) |
679 | { | 688 | { |
680 | int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO; | 689 | enum kvm_bus bus_idx; |
681 | enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS; | ||
682 | struct _ioeventfd *p; | 690 | struct _ioeventfd *p; |
683 | struct eventfd_ctx *eventfd; | 691 | struct eventfd_ctx *eventfd; |
684 | int ret; | 692 | int ret; |
685 | 693 | ||
694 | bus_idx = ioeventfd_bus_from_flags(args->flags); | ||
686 | /* must be natural-word sized */ | 695 | /* must be natural-word sized */ |
687 | switch (args->len) { | 696 | switch (args->len) { |
688 | case 1: | 697 | case 1: |
@@ -757,12 +766,12 @@ fail: | |||
757 | static int | 766 | static int |
758 | kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) | 767 | kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) |
759 | { | 768 | { |
760 | int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO; | 769 | enum kvm_bus bus_idx; |
761 | enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS; | ||
762 | struct _ioeventfd *p, *tmp; | 770 | struct _ioeventfd *p, *tmp; |
763 | struct eventfd_ctx *eventfd; | 771 | struct eventfd_ctx *eventfd; |
764 | int ret = -ENOENT; | 772 | int ret = -ENOENT; |
765 | 773 | ||
774 | bus_idx = ioeventfd_bus_from_flags(args->flags); | ||
766 | eventfd = eventfd_ctx_fdget(args->fd); | 775 | eventfd = eventfd_ctx_fdget(args->fd); |
767 | if (IS_ERR(eventfd)) | 776 | if (IS_ERR(eventfd)) |
768 | return PTR_ERR(eventfd); | 777 | return PTR_ERR(eventfd); |