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"); } }
static void ivshmem_write_config(PCIDevice *pdev, uint32_t address, uint32_t val, int len) { IVShmemState *s = IVSHMEM_COMMON(pdev); int is_enabled, was_enabled = msix_enabled(pdev); pci_default_write_config(pdev, address, val, len); is_enabled = msix_enabled(pdev); if (kvm_msi_via_irqfd_enabled()) { if (!was_enabled && is_enabled) { ivshmem_enable_irqfd(s); } else if (was_enabled && !is_enabled) { ivshmem_disable_irqfd(s); } } }