git: 1ea0721e1a56 - main - vtgpu: Support virtio gpu on Parallels Desktop
Date: Tue, 10 Feb 2026 17:07:16 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=1ea0721e1a566fdb552b0a919c22667844a894d9
commit 1ea0721e1a566fdb552b0a919c22667844a894d9
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2026-02-10 17:06:31 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-02-10 17:06:31 +0000
vtgpu: Support virtio gpu on Parallels Desktop
The Parallels Desktop Virtio GPU implementation doesn't handle
enqueuing the VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING request and
memory list together.
Work around this by splitting them before sending them to be enqueued.
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D55147
---
sys/dev/virtio/gpu/virtio_gpu.c | 51 ++++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 13 deletions(-)
diff --git a/sys/dev/virtio/gpu/virtio_gpu.c b/sys/dev/virtio/gpu/virtio_gpu.c
index 668eb170304a..b95bae9fe286 100644
--- a/sys/dev/virtio/gpu/virtio_gpu.c
+++ b/sys/dev/virtio/gpu/virtio_gpu.c
@@ -445,21 +445,33 @@ vtgpu_alloc_virtqueue(struct vtgpu_softc *sc)
}
static int
-vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen,
- void *resp, size_t resplen)
+vtgpu_req_resp2(struct vtgpu_softc *sc, void *req1, size_t req1len,
+ void *req2, size_t req2len, void *resp, size_t resplen)
{
struct sglist sg;
- struct sglist_seg segs[2];
- int error;
+ struct sglist_seg segs[3];
+ int error, rcount;
- sglist_init(&sg, 2, segs);
+ sglist_init(&sg, 3, segs);
- error = sglist_append(&sg, req, reqlen);
+ rcount = 1;
+ error = sglist_append(&sg, req1, req1len);
if (error != 0) {
device_printf(sc->vtgpu_dev,
- "Unable to append the request to the sglist: %d\n", error);
+ "Unable to append the request to the sglist: %d\n",
+ error);
return (error);
}
+ if (req2 != NULL) {
+ error = sglist_append(&sg, req2, req2len);
+ if (error != 0) {
+ device_printf(sc->vtgpu_dev,
+ "Unable to append the request to the sglist: %d\n",
+ error);
+ return (error);
+ }
+ rcount++;
+ }
error = sglist_append(&sg, resp, resplen);
if (error != 0) {
device_printf(sc->vtgpu_dev,
@@ -467,7 +479,7 @@ vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen,
error);
return (error);
}
- error = virtqueue_enqueue(sc->vtgpu_ctrl_vq, resp, &sg, 1, 1);
+ error = virtqueue_enqueue(sc->vtgpu_ctrl_vq, resp, &sg, rcount, 1);
if (error != 0) {
device_printf(sc->vtgpu_dev, "Enqueue failed: %d\n", error);
return (error);
@@ -479,6 +491,13 @@ vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen,
return (0);
}
+static int
+vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen,
+ void *resp, size_t resplen)
+{
+ return (vtgpu_req_resp2(sc, req, reqlen, NULL, 0, resp, resplen));
+}
+
static int
vtgpu_get_display_info(struct vtgpu_softc *sc)
{
@@ -559,9 +578,15 @@ static int
vtgpu_attach_backing(struct vtgpu_softc *sc)
{
struct {
+ /*
+ * Split the backing and mem request arguments as some
+ * hypervisors, e.g. Parallels Desktop, don't work when
+ * they are enqueued together.
+ */
struct {
struct virtio_gpu_resource_attach_backing backing;
- struct virtio_gpu_mem_entry mem[1];
+ char pad;
+ struct virtio_gpu_mem_entry mem;
} req;
char pad;
struct virtio_gpu_ctrl_hdr resp;
@@ -577,11 +602,11 @@ vtgpu_attach_backing(struct vtgpu_softc *sc)
s.req.backing.resource_id = htole32(VTGPU_RESOURCE_ID);
s.req.backing.nr_entries = htole32(1);
- s.req.mem[0].addr = htole64(sc->vtgpu_fb_info.fb_pbase);
- s.req.mem[0].length = htole32(sc->vtgpu_fb_info.fb_size);
+ s.req.mem.addr = htole64(sc->vtgpu_fb_info.fb_pbase);
+ s.req.mem.length = htole32(sc->vtgpu_fb_info.fb_size);
- error = vtgpu_req_resp(sc, &s.req, sizeof(s.req), &s.resp,
- sizeof(s.resp));
+ error = vtgpu_req_resp2(sc, &s.req.backing, sizeof(s.req.backing),
+ &s.req.mem, sizeof(s.req.mem), &s.resp, sizeof(s.resp));
if (error != 0)
return (error);