aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2023-01-09 17:14:19 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2023-01-23 19:21:36 +0000
commit6f5141456ed07a24097c2cf3d6c389bf971d78d2 (patch)
tree61c94e9aa3100c29e3898553ecf82f14ec0c97a9
parent5644850620aead7c257a4e3040e20201b510f499 (diff)
downloadsrc-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.c46
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);