Index: sys/dev/pv/virtio.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/dev/pv/virtio.c,v diff -u -p -u -p -r1.36 virtio.c --- sys/dev/pv/virtio.c 20 Dec 2024 22:18:27 -0000 1.36 +++ sys/dev/pv/virtio.c 8 Jan 2025 19:57:47 -0000 @@ -167,6 +167,8 @@ virtio_attach_finish(struct virtio_softc for (i = 0; i < sc->sc_nvqs; i++) { struct virtqueue *vq = &sc->sc_vqs[i]; + if (vq->vq_num == 0) + continue; virtio_setup_queue(sc, vq, vq->vq_dmamap->dm_segs[0].ds_addr); } virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); @@ -185,9 +187,9 @@ virtio_reinit_start(struct virtio_softc for (i = 0; i < sc->sc_nvqs; i++) { int n; struct virtqueue *vq = &sc->sc_vqs[i]; - n = virtio_read_queue_size(sc, vq->vq_index); - if (n == 0) /* vq disappeared */ + if (vq->vq_num == 0) /* not used */ continue; + n = virtio_read_queue_size(sc, vq->vq_index); if (n != vq->vq_num) { panic("%s: virtqueue size changed, vq index %d", sc->sc_dev.dv_xname, vq->vq_index); @@ -274,8 +276,11 @@ virtio_check_vqs(struct virtio_softc *sc int i, r = 0; /* going backwards is better for if_vio */ - for (i = sc->sc_nvqs - 1; i >= 0; i--) + for (i = sc->sc_nvqs - 1; i >= 0; i--) { + if (sc->sc_vqs[i].vq_num == 0) /* not used */ + continue; r |= virtio_check_vq(sc, &sc->sc_vqs[i]); + } return r; } @@ -305,6 +310,7 @@ virtio_init_vq(struct virtio_softc *sc, int i, j; int vq_size = vq->vq_num; + VIRTIO_ASSERT(vq_size > 0); memset(vq->vq_vaddr, 0, vq->vq_bytesize); /* build the indirect descriptor chain */ @@ -468,6 +474,11 @@ virtio_free_vq(struct virtio_softc *sc, struct vq_entry *qe; int i = 0; + if (vq->vq_num == 0) { + /* virtio_alloc_vq() was never called */ + return 0; + } + /* device must be already deactivated */ /* confirm the vq is empty */ SLIST_FOREACH(qe, &vq->vq_freelist, qe_list) { @@ -1017,6 +1028,10 @@ virtio_vq_dump(struct virtqueue *vq) #endif /* Common fields */ printf(" + addr: %p\n", vq); + if (vq->vq_num == 0) { + printf(" + vq is unused\n"); + return; + } printf(" + vq num: %d\n", vq->vq_num); printf(" + vq mask: 0x%X\n", vq->vq_mask); printf(" + vq index: %d\n", vq->vq_index); Index: sys/dev/pv/virtiovar.h =================================================================== RCS file: /mount/openbsd/cvs/src/sys/dev/pv/virtiovar.h,v diff -u -p -u -p -r1.26 virtiovar.h --- sys/dev/pv/virtiovar.h 20 Dec 2024 22:18:27 -0000 1.26 +++ sys/dev/pv/virtiovar.h 8 Jan 2025 19:57:47 -0000 @@ -103,7 +103,8 @@ struct vq_entry { struct virtqueue { struct virtio_softc *vq_owner; - unsigned int vq_num; /* queue size (# of entries) */ + unsigned int vq_num; /* queue size (# of entries), + * 0 if unused/non-existant */ unsigned int vq_mask; /* (1 << vq_num - 1) */ int vq_index; /* queue number (0, 1, ...) */ @@ -180,7 +181,7 @@ struct virtio_softc { int sc_indirect; int sc_version_1; - int sc_nvqs; /* set by child */ + int sc_nvqs; /* size of sc_vqs, set by child */ struct virtqueue *sc_vqs; /* set by child */ struct device *sc_child; /* set by child,