1
0
Fork 0

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>
hifive-unleashed-5.1
Cornelia Huck 2013-02-28 12:33:20 +01:00 committed by Marcelo Tosatti
parent 060f0ce6ff
commit 2b83451b45
3 changed files with 24 additions and 4 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 @@ fail:
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);