static void setup_interrupt(IVShmemState *s, int vector, Error **errp) { EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; bool with_irqfd = kvm_msi_via_irqfd_enabled() && ivshmem_has_feature(s, IVSHMEM_MSI); PCIDevice *pdev = PCI_DEVICE(s); Error *err = NULL; IVSHMEM_DPRINTF("setting up interrupt for vector: %d\n", vector); if (!with_irqfd) { IVSHMEM_DPRINTF("with eventfd\n"); watch_vector_notifier(s, n, vector); } else if (msix_enabled(pdev)) { IVSHMEM_DPRINTF("with irqfd\n"); ivshmem_add_kvm_msi_virq(s, vector, &err); if (err) { error_propagate(errp, err); return; } if (!msix_is_masked(pdev, vector)) { kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, s->msi_vectors[vector].virq); /* TODO handle error */ } } else { /* it will be delayed until msix is enabled, in write_config */ IVSHMEM_DPRINTF("with irqfd, delayed until msix enabled\n"); } }
static void setup_interrupt(IVShmemState *s, int vector) { EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; bool with_irqfd = kvm_msi_via_irqfd_enabled() && ivshmem_has_feature(s, IVSHMEM_MSI); PCIDevice *pdev = PCI_DEVICE(s); IVSHMEM_DPRINTF("setting up interrupt for vector: %d\n", vector); if (!with_irqfd) { IVSHMEM_DPRINTF("with eventfd"); s->eventfd_chr[vector] = create_eventfd_chr_device(s, n, vector); } else if (msix_enabled(pdev)) { IVSHMEM_DPRINTF("with irqfd"); if (ivshmem_add_kvm_msi_virq(s, vector) < 0) { return; } if (!msix_is_masked(pdev, vector)) { kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, s->msi_vectors[vector].virq); } } else { /* it will be delayed until msix is enabled, in write_config */ IVSHMEM_DPRINTF("with irqfd, delayed until msix enabled"); } }
HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint, HvSintAckClb sint_ack_clb) { HvSintRoute *sint_route; int r, gsi; sint_route = g_malloc0(sizeof(*sint_route)); r = event_notifier_init(&sint_route->sint_set_notifier, false); if (r) { goto err; } r = event_notifier_init(&sint_route->sint_ack_notifier, false); if (r) { goto err_sint_set_notifier; } event_notifier_set_handler(&sint_route->sint_ack_notifier, false, kvm_hv_sint_ack_handler); gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vcpu_id, sint); if (gsi < 0) { goto err_gsi; } r = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, &sint_route->sint_set_notifier, &sint_route->sint_ack_notifier, gsi); if (r) { goto err_irqfd; } sint_route->gsi = gsi; sint_route->sint_ack_clb = sint_ack_clb; sint_route->vcpu_id = vcpu_id; sint_route->sint = sint; return sint_route; err_irqfd: kvm_irqchip_release_virq(kvm_state, gsi); err_gsi: event_notifier_set_handler(&sint_route->sint_ack_notifier, false, NULL); event_notifier_cleanup(&sint_route->sint_ack_notifier); err_sint_set_notifier: event_notifier_cleanup(&sint_route->sint_set_notifier); err: g_free(sint_route); return NULL; }
static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, MSIMessage msg) { IVShmemState *s = IVSHMEM(dev); EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; MSIVector *v = &s->msi_vectors[vector]; int ret; IVSHMEM_DPRINTF("vector unmask %p %d\n", dev, vector); ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev); if (ret < 0) { return ret; } return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq); }