Index | Thread | Search

From:
Helg <helg-openbsd@gmx.de>
Subject:
viogpu: return correct pointer from mmap (X11 now works)
To:
tech@openbsd.org
Cc:
mark.kettenis@xs4all.nl
Date:
Sun, 4 Jan 2026 12:32:33 +0100

Download raw body.

Thread
Hi tech@

viogpu_wsmmap() returns a kva but instead should return a physical
address via bus_dmamem_mmap(9). Without this, QEMU would only show a
black screen when starting X11. On the Apple Hypervisor, the kernel
would panic.

Also add calls to bus_dmamap_sync(9) before transferring the framebuffer
to host memory. It was working for me without this, but this ensures
that the host running on another CPU will see updates to the
framebuffer.

Thanks to kettins@ for help with this.

ok?


Index: viogpu.c
===================================================================
RCS file: /cvs/src/sys/dev/pv/viogpu.c,v
diff -u -p -r1.12 viogpu.c
--- viogpu.c	16 Jan 2025 10:33:27 -0000	1.12
+++ viogpu.c	4 Jan 2026 13:46:52 -0000
@@ -539,6 +539,7 @@ int
 viogpu_transfer_to_host_2d(struct viogpu_softc *sc, int resource_id,
     uint32_t width, uint32_t height)
 {
+	struct virtio_softc *vsc = sc->sc_virtio;
 	struct virtio_gpu_transfer_to_host_2d tth = { 0 };
 	struct virtio_gpu_ctrl_hdr resp = { 0 };
 
@@ -547,6 +548,9 @@ viogpu_transfer_to_host_2d(struct viogpu
 	tth.r.width = width;
 	tth.r.height = height;
 
+	bus_dmamap_sync(vsc->sc_dmat, sc->sc_fb_dma_map, 0, sc->sc_fb_dma_size,
+	    BUS_DMASYNC_PREWRITE);
+
 	viogpu_send_cmd(sc, &tth, sizeof(tth), &resp, sizeof(resp));
 
 	if (resp.type != VIRTIO_GPU_RESP_OK_NODATA) {
@@ -555,6 +559,9 @@ viogpu_transfer_to_host_2d(struct viogpu
 		return 1;
 	}
 
+	bus_dmamap_sync(vsc->sc_dmat, sc->sc_fb_dma_map, 0, sc->sc_fb_dma_size,
+	    BUS_DMASYNC_POSTWRITE);
+
 	return 0;
 }
 
@@ -632,12 +639,15 @@ viogpu_wsmmap(void *v, off_t off, int pr
 {
 	struct rasops_info *ri = v;
 	struct viogpu_softc *sc = ri->ri_hw;
+	struct virtio_softc *vsc = sc->sc_virtio;
 	size_t size = sc->sc_fb_dma_size;
+	bus_dma_segment_t segs = sc->sc_fb_dma_seg;
 
 	if (off < 0 || off >= size)
 		return -1;
 
-	return (((paddr_t)sc->sc_fb_dma_kva + off) | PMAP_NOCACHE);
+	return bus_dmamem_mmap(vsc->sc_dmat, &segs, 1, off, prot,
+	    BUS_DMA_WAITOK);
 }
 
 int