diff options
author | Mitchell Horne <mhorne@FreeBSD.org> | 2023-01-09 17:14:19 +0000 |
---|---|---|
committer | Mitchell Horne <mhorne@FreeBSD.org> | 2023-01-23 19:21:36 +0000 |
commit | 6f5141456ed07a24097c2cf3d6c389bf971d78d2 (patch) | |
tree | 61c94e9aa3100c29e3898553ecf82f14ec0c97a9 | |
parent | 5644850620aead7c257a4e3040e20201b510f499 (diff) | |
download | src-6f5141456ed07a24097c2cf3d6c389bf971d78d2.tar.gz src-6f5141456ed07a24097c2cf3d6c389bf971d78d2.zip |
vtblk: secondary fix for dumping
The code paths while dumping do not got through busdma. As such,
safeguard against calling bus_dmamap_sync() with a NULL map. The x86
implementation tolerates this but others do not, resulting in a
NULL dereference panic when dumping to a vtblk device on arm64, riscv,
etc.
Fixes: 782105f7c898 ("vtblk: Use busdma")
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D37990
-rw-r--r-- | sys/dev/virtio/block/virtio_blk.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/sys/dev/virtio/block/virtio_blk.c b/sys/dev/virtio/block/virtio_blk.c index 052017251c22..0e66cd3c89db 100644 --- a/sys/dev/virtio/block/virtio_blk.c +++ b/sys/dev/virtio/block/virtio_blk.c @@ -1126,15 +1126,17 @@ vtblk_request_execute_cb(void * callback_arg, bus_dma_segment_t * segs, sglist_append(sg, &req->vbr_ack, sizeof(uint8_t)); readable = sg->sg_nseg - writable; - switch (bp->bio_cmd) { - case BIO_READ: - bus_dmamap_sync(sc->vtblk_dmat, req->vbr_mapp, - BUS_DMASYNC_PREREAD); - break; - case BIO_WRITE: - bus_dmamap_sync(sc->vtblk_dmat, req->vbr_mapp, - BUS_DMASYNC_PREWRITE); - break; + if (req->vbr_mapp != NULL) { + switch (bp->bio_cmd) { + case BIO_READ: + bus_dmamap_sync(sc->vtblk_dmat, req->vbr_mapp, + BUS_DMASYNC_PREREAD); + break; + case BIO_WRITE: + bus_dmamap_sync(sc->vtblk_dmat, req->vbr_mapp, + BUS_DMASYNC_PREWRITE); + break; + } } error = virtqueue_enqueue(vq, req, sg, readable, writable); @@ -1191,17 +1193,21 @@ vtblk_queue_completed(struct vtblk_softc *sc, struct bio_queue *queue) } bp = req->vbr_bp; - switch (bp->bio_cmd) { - case BIO_READ: - bus_dmamap_sync(sc->vtblk_dmat, req->vbr_mapp, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->vtblk_dmat, req->vbr_mapp); - break; - case BIO_WRITE: - bus_dmamap_sync(sc->vtblk_dmat, req->vbr_mapp, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->vtblk_dmat, req->vbr_mapp); - break; + if (req->vbr_mapp != NULL) { + switch (bp->bio_cmd) { + case BIO_READ: + bus_dmamap_sync(sc->vtblk_dmat, req->vbr_mapp, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->vtblk_dmat, + req->vbr_mapp); + break; + case BIO_WRITE: + bus_dmamap_sync(sc->vtblk_dmat, req->vbr_mapp, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->vtblk_dmat, + req->vbr_mapp); + break; + } } bp->bio_error = vtblk_request_error(req); TAILQ_INSERT_TAIL(queue, bp, bio_queue); |