The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=1ea0721e1a566fdb552b0a919c22667844a894d9

commit 1ea0721e1a566fdb552b0a919c22667844a894d9
Author:     Andrew Turner <[email protected]>
AuthorDate: 2026-02-10 17:06:31 +0000
Commit:     Andrew Turner <[email protected]>
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);
 

Reply via email to