Index: legacy_irq.c =================================================================== --- legacy_irq.c (revision 258570) +++ legacy_irq.c (working copy) @@ -58,7 +58,8 @@ { int i; - assert(irq < NLIRQ); + if (irq >= NLIRQ) + return (irq); if (irq < 0) { for (i = 0; i < NLIRQ; i++) { Index: pci_virtio_block.c =================================================================== --- pci_virtio_block.c (revision 258570) +++ pci_virtio_block.c (working copy) @@ -117,6 +117,7 @@ */ struct pci_vtblk_softc { struct virtio_softc vbsc_vs; + pthread_mutex_t vsc_mtx; struct vqueue_info vbsc_vq; int vbsc_fd; struct vtblk_config vbsc_cfg; @@ -304,8 +305,12 @@ /* record fd of storage device/file */ sc->vbsc_fd = fd; + pthread_mutex_init(&sc->vsc_mtx, NULL); + /* init virtio softc and virtqueues */ vi_softc_linkup(&sc->vbsc_vs, &vtblk_vi_consts, sc, pi, &sc->vbsc_vq); + sc->vbsc_vs.vs_mtx = &sc->vsc_mtx; + sc->vbsc_vq.vq_qsize = VTBLK_RINGSZ; /* sc->vbsc_vq.vq_notify = we have no per-queue notify */ @@ -339,6 +344,8 @@ pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_BLOCK); + pci_lintr_request(pi, 20); + if (vi_intr_init(&sc->vbsc_vs, 1, fbsdrun_virtio_msix())) return (1); vi_set_io_bar(&sc->vbsc_vs, 0); Index: pci_virtio_net.c =================================================================== --- pci_virtio_net.c (revision 258570) +++ pci_virtio_net.c (working copy) @@ -519,6 +519,8 @@ pthread_mutex_init(&sc->vsc_mtx, NULL); vi_softc_linkup(&sc->vsc_vs, &vtnet_vi_consts, sc, pi, sc->vsc_queues); + sc->vsc_vs.vs_mtx = &sc->vsc_mtx; + sc->vsc_queues[VTNET_RXQ].vq_qsize = VTNET_RINGSZ; sc->vsc_queues[VTNET_RXQ].vq_notify = pci_vtnet_ping_rxq; sc->vsc_queues[VTNET_TXQ].vq_qsize = VTNET_RINGSZ; @@ -608,6 +610,8 @@ pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); + pci_lintr_request(pi, 20); + /* link always up */ sc->vsc_config.status = 1; Index: virtio.c =================================================================== --- virtio.c (revision 258570) +++ virtio.c (working copy) @@ -99,7 +99,11 @@ vs->vs_negotiated_caps = 0; vs->vs_curq = 0; /* vs->vs_status = 0; -- redundant */ + VS_LOCK(vs); + if (vs->vs_isr) + pci_lintr_deassert(vs->vs_pi); vs->vs_isr = 0; + VS_UNLOCK(vs); vs->vs_msix_cfg_idx = VIRTIO_MSI_NO_VECTOR; } @@ -139,8 +143,10 @@ return (1); } else { vs->vs_flags &= ~VIRTIO_USE_MSIX; +#if 0 /* Only 1 MSI vector for bhyve */ pci_emul_add_msicap(vs->vs_pi, 1); +#endif } return (0); } @@ -591,6 +597,8 @@ case VTCFG_R_ISR: value = vs->vs_isr; vs->vs_isr = 0; /* a read clears this flag */ + if (value) + pci_lintr_deassert(pi); break; case VTCFG_R_CFGVEC: value = vs->vs_msix_cfg_idx; Index: virtio.h =================================================================== --- virtio.h (revision 258570) +++ virtio.h (working copy) @@ -328,6 +328,18 @@ uint16_t vs_msix_cfg_idx; /* MSI-X vector for config event */ }; +#define VS_LOCK(vs) \ +do { \ + if (vs->vs_mtx) \ + pthread_mutex_lock(vs->vs_mtx); \ +} while (0) + +#define VS_UNLOCK(vs) \ +do { \ + if (vs->vs_mtx) \ + pthread_mutex_unlock(vs->vs_mtx); \ +} while (0) + struct virtio_consts { const char *vc_name; /* name of driver (for diagnostics) */ int vc_nvq; /* number of virtual queues */ @@ -434,8 +446,10 @@ if (vs->vs_flags & VIRTIO_USE_MSIX) pci_generate_msix(vs->vs_pi, vq->vq_msix_idx); else { + VS_LOCK(vs); vs->vs_isr |= VTCFG_ISR_QUEUES; - pci_generate_msi(vs->vs_pi, 0); + pci_lintr_assert(vs->vs_pi); + VS_UNLOCK(vs); } }