KVM: ioeventfd for virtio-ccw devices.
authorCornelia Huck <cornelia.huck@de.ibm.com>
Thu, 28 Feb 2013 11:33:20 +0000 (12:33 +0100)
committerMarcelo Tosatti <mtosatti@redhat.com>
Tue, 5 Mar 2013 22:12:17 +0000 (19:12 -0300)
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>
Documentation/virtual/kvm/api.txt
include/uapi/linux/kvm.h
virt/kvm/eventfd.c

index 119358d..c16b442 100644 (file)
@@ -1486,15 +1486,23 @@ struct kvm_ioeventfd {
        __u8  pad[36];
 };
 
+For the special case of virtio-ccw devices on s390, the ioevent is matched
+to a subchannel/virtqueue tuple instead.
+
 The following flags are defined:
 
 #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
 #define KVM_IOEVENTFD_FLAG_PIO       (1 << kvm_ioeventfd_flag_nr_pio)
 #define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
+#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \
+       (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify)
 
 If datamatch flag is set, the event will be signaled only if the written value
 to the registered address is equal to datamatch in struct kvm_ioeventfd.
 
+For virtio-ccw devices, addr contains the subchannel id and datamatch the
+virtqueue index.
+
 
 4.60 KVM_DIRTY_TLB
 
index 3c56ba3..74d0ff3 100644 (file)
@@ -449,12 +449,15 @@ enum {
        kvm_ioeventfd_flag_nr_datamatch,
        kvm_ioeventfd_flag_nr_pio,
        kvm_ioeventfd_flag_nr_deassign,
+       kvm_ioeventfd_flag_nr_virtio_ccw_notify,
        kvm_ioeventfd_flag_nr_max,
 };
 
 #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
 #define KVM_IOEVENTFD_FLAG_PIO       (1 << kvm_ioeventfd_flag_nr_pio)
 #define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
+#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \
+       (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify)
 
 #define KVM_IOEVENTFD_VALID_FLAG_MASK  ((1 << kvm_ioeventfd_flag_nr_max) - 1)
 
index 0b6fe69..020522e 100644 (file)
@@ -674,15 +674,24 @@ ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
        return false;
 }
 
+static enum kvm_bus ioeventfd_bus_from_flags(__u32 flags)
+{
+       if (flags & KVM_IOEVENTFD_FLAG_PIO)
+               return KVM_PIO_BUS;
+       if (flags & KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY)
+               return KVM_VIRTIO_CCW_NOTIFY_BUS;
+       return KVM_MMIO_BUS;
+}
+
 static int
 kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
 {
-       int                       pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
-       enum kvm_bus              bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
+       enum kvm_bus              bus_idx;
        struct _ioeventfd        *p;
        struct eventfd_ctx       *eventfd;
        int                       ret;
 
+       bus_idx = ioeventfd_bus_from_flags(args->flags);
        /* must be natural-word sized */
        switch (args->len) {
        case 1:
@@ -757,12 +766,12 @@ fail:
 static int
 kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
 {
-       int                       pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
-       enum kvm_bus              bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
+       enum kvm_bus              bus_idx;
        struct _ioeventfd        *p, *tmp;
        struct eventfd_ctx       *eventfd;
        int                       ret = -ENOENT;
 
+       bus_idx = ioeventfd_bus_from_flags(args->flags);
        eventfd = eventfd_ctx_fdget(args->fd);
        if (IS_ERR(eventfd))
                return PTR_ERR(eventfd);