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>
This commit is contained in:
Родитель
060f0ce6ff
Коммит
2b83451b45
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче