Equip irqfd with polarity, so it can emulate the low-active interrupt. We take one extra bit in flags to pass this info to kernel and keep the default value "zero" as high-active.
Signed-off-by: Liu Ping Fan <pingf...@linux.vnet.ibm.com> --- The kernel will extend this interface correspondingly --- hw/misc/vfio.c | 4 ++-- hw/virtio/virtio-pci.c | 2 +- include/sysemu/kvm.h | 3 ++- kvm-all.c | 14 ++++++++------ linux-headers/linux/kvm.h | 3 +++ 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index a1c08fb..f1fb761 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -646,7 +646,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1; if (vector->virq < 0 || kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, - NULL, vector->virq) < 0) { + NULL, vector->virq, 0) < 0) { if (vector->virq >= 0) { kvm_irqchip_release_virq(kvm_state, vector->virq); vector->virq = -1; @@ -814,7 +814,7 @@ retry: vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg); if (vector->virq < 0 || kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, - NULL, vector->virq) < 0) { + NULL, vector->virq, 0) < 0) { qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt), vfio_msi_interrupt, NULL, vector); } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index f2c489b..a8dbb4f 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -508,7 +508,7 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy, VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no); EventNotifier *n = virtio_queue_get_guest_notifier(vq); int ret; - ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq); + ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq, 0); return ret; } diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 47cc012..a990db7 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -309,8 +309,9 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg); int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg); void kvm_irqchip_release_virq(KVMState *s, int virq); +/* polarity: 0 high-active */ int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, - EventNotifier *rn, int virq); + EventNotifier *rn, int virq, int polarity); int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq); int kvm_pc_route_gsi(void *opaque, int n); void kvm_pc_gsi_handler(void *opaque, int n, int level); diff --git a/kvm-all.c b/kvm-all.c index 875e32e..d0e457b 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1231,12 +1231,13 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) } static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int rfd, int virq, - bool assign) + bool assign, int polarity) { struct kvm_irqfd irqfd = { .fd = fd, .gsi = virq, - .flags = assign ? 0 : KVM_IRQFD_FLAG_DEASSIGN, + .flags = (assign ? 0 : KVM_IRQFD_FLAG_DEASSIGN) + | (polarity ? 0 : KVM_IRQFD_FLAG_POLARITY), }; if (rfd != -1) { @@ -1271,7 +1272,8 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) return -ENOSYS; } -static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign) +static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign, + int polarity) { abort(); } @@ -1283,16 +1285,16 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) #endif /* !KVM_CAP_IRQ_ROUTING */ int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, - EventNotifier *rn, int virq) + EventNotifier *rn, int virq, int polarity) { return kvm_irqchip_assign_irqfd(s, event_notifier_get_fd(n), - rn ? event_notifier_get_fd(rn) : -1, virq, true); + rn ? event_notifier_get_fd(rn) : -1, virq, true, polarity); } int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq) { return kvm_irqchip_assign_irqfd(s, event_notifier_get_fd(n), -1, virq, - false); + false, 0); } static int kvm_irqchip_create(KVMState *s) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index c614070..64afc8a 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -740,6 +740,9 @@ struct kvm_xen_hvm_config { */ #define KVM_IRQFD_FLAG_RESAMPLE (1 << 1) +/* 0: high-active */ +#define KVM_IRQFD_FLAG_POLARITY (1<<2) + struct kvm_irqfd { __u32 fd; __u32 gsi; -- 1.8.1.4