Commit 2b83451b authored by Cornelia Huck's avatar Cornelia Huck Committed by Marcelo Tosatti

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: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 060f0ce6
...@@ -1486,15 +1486,23 @@ struct kvm_ioeventfd { ...@@ -1486,15 +1486,23 @@ struct kvm_ioeventfd {
__u8 pad[36]; __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: The following flags are defined:
#define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) #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_PIO (1 << kvm_ioeventfd_flag_nr_pio)
#define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) #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 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. 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 4.60 KVM_DIRTY_TLB
......
...@@ -449,12 +449,15 @@ enum { ...@@ -449,12 +449,15 @@ enum {
kvm_ioeventfd_flag_nr_datamatch, kvm_ioeventfd_flag_nr_datamatch,
kvm_ioeventfd_flag_nr_pio, kvm_ioeventfd_flag_nr_pio,
kvm_ioeventfd_flag_nr_deassign, kvm_ioeventfd_flag_nr_deassign,
kvm_ioeventfd_flag_nr_virtio_ccw_notify,
kvm_ioeventfd_flag_nr_max, kvm_ioeventfd_flag_nr_max,
}; };
#define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) #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_PIO (1 << kvm_ioeventfd_flag_nr_pio)
#define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) #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) #define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1)
......
...@@ -674,15 +674,24 @@ ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p) ...@@ -674,15 +674,24 @@ ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
return false; 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 static int
kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
{ {
int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO; enum kvm_bus bus_idx;
enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
struct _ioeventfd *p; struct _ioeventfd *p;
struct eventfd_ctx *eventfd; struct eventfd_ctx *eventfd;
int ret; int ret;
bus_idx = ioeventfd_bus_from_flags(args->flags);
/* must be natural-word sized */ /* must be natural-word sized */
switch (args->len) { switch (args->len) {
case 1: case 1:
...@@ -757,12 +766,12 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) ...@@ -757,12 +766,12 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
static int static int
kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
{ {
int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO; enum kvm_bus bus_idx;
enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
struct _ioeventfd *p, *tmp; struct _ioeventfd *p, *tmp;
struct eventfd_ctx *eventfd; struct eventfd_ctx *eventfd;
int ret = -ENOENT; int ret = -ENOENT;
bus_idx = ioeventfd_bus_from_flags(args->flags);
eventfd = eventfd_ctx_fdget(args->fd); eventfd = eventfd_ctx_fdget(args->fd);
if (IS_ERR(eventfd)) if (IS_ERR(eventfd))
return PTR_ERR(eventfd); return PTR_ERR(eventfd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment