[libvirt] [PATCH v4 19/20] qemu: build vhost-user GPU devices

marcandre.lureau at redhat.com marcandre.lureau at redhat.com
Fri Sep 13 12:50:56 UTC 2019


From: Marc-André Lureau <marcandre.lureau at redhat.com>

For each vhost-user GPUs,
- build a socket chardev, and pass the vhost-user socket to it
- build a vhost-user video device and associate it with the chardev

Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
---
 src/qemu/qemu_command.c                    | 56 +++++++++++++++++++---
 tests/qemuxml2argvdata/virtio-options.args |  4 +-
 2 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0a9110f3fa..3b87952bfb 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4526,16 +4526,23 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
                         virQEMUCapsPtr qemuCaps)
 {
     VIR_AUTOCLEAN(virBuffer) buf = VIR_BUFFER_INITIALIZER;
-    const char *model;
+    const char *model = NULL;
 
     /* We try to chose the best model for primary video device by preferring
      * model with VGA compatibility mode.  For some video devices on some
      * architectures there might not be such model so fallback to one
      * without VGA compatibility mode. */
-    if (video->primary && qemuDomainSupportsVideoVga(video, qemuCaps))
-        model = qemuDeviceVideoTypeToString(video->type);
-    else
-        model = qemuDeviceVideoSecondaryTypeToString(video->type);
+    if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
+        if (video->primary && qemuDomainSupportsVideoVga(video, qemuCaps))
+            model = "vhost-user-vga";
+        else
+            model = "vhost-user-gpu";
+    } else {
+        if (video->primary && qemuDomainSupportsVideoVga(video, qemuCaps))
+            model = qemuDeviceVideoTypeToString(video->type);
+        else
+            model = qemuDeviceVideoSecondaryTypeToString(video->type);
+    }
 
     if (!model || STREQ(model, "")) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -4544,8 +4551,8 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
         return NULL;
     }
 
-    if (STREQ(model, "virtio-gpu")) {
-        if (qemuBuildVirtioDevStr(&buf, "virtio-gpu", qemuCaps,
+    if (STREQ(model, "virtio-gpu") || STREQ(model, "vhost-user-gpu")) {
+        if (qemuBuildVirtioDevStr(&buf, model, qemuCaps,
                                   VIR_DOMAIN_DEVICE_VIDEO, video) < 0) {
             return NULL;
         }
@@ -4588,6 +4595,10 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
             if (video->heads)
                 virBufferAsprintf(&buf, ",max_outputs=%u", video->heads);
         }
+    } else if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
+        if (video->heads)
+            virBufferAsprintf(&buf, ",max_outputs=%u", video->heads);
+        virBufferAsprintf(&buf, ",chardev=chr-vu-%s", video->info.alias);
     } else if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
         if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS)) {
             if (video->heads)
@@ -4699,6 +4710,23 @@ qemuBuildVgaVideoCommand(virCommandPtr cmd,
 }
 
 
+static char *
+qemuBuildVhostUserChardevStr(const char *alias,
+                             int *fd,
+                             virCommandPtr cmd)
+{
+    char *chardev = NULL;
+
+    if (virAsprintf(&chardev, "socket,id=chr-vu-%s,fd=%d", alias, *fd) < 0)
+        return NULL;
+
+    virCommandPassFD(cmd, *fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+    *fd = -1;
+
+    return chardev;
+}
+
+
 static int
 qemuBuildVideoCommandLine(virCommandPtr cmd,
                           const virDomainDef *def,
@@ -4706,6 +4734,20 @@ qemuBuildVideoCommandLine(virCommandPtr cmd,
 {
     size_t i;
 
+    for (i = 0; i < def->nvideos; i++) {
+        VIR_AUTOFREE(char *) chardev = NULL;
+        virDomainVideoDefPtr video = def->videos[i];
+
+        if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
+            if (!(chardev = qemuBuildVhostUserChardevStr(video->info.alias,
+                                &QEMU_DOMAIN_VIDEO_PRIVATE(video)->vhost_user_fd,
+                                cmd)))
+                return -1;
+
+            virCommandAddArgList(cmd, "-chardev", chardev, NULL);
+        }
+    }
+
     for (i = 0; i < def->nvideos; i++) {
         VIR_AUTOFREE(char *) str = NULL;
         virDomainVideoDefPtr video = def->videos[i];
diff --git a/tests/qemuxml2argvdata/virtio-options.args b/tests/qemuxml2argvdata/virtio-options.args
index 92bce8283c..79216a5503 100644
--- a/tests/qemuxml2argvdata/virtio-options.args
+++ b/tests/qemuxml2argvdata/virtio-options.args
@@ -49,7 +49,9 @@ ats=on \
 ats=on \
 -device virtio-input-host-pci,id=input3,evdev=/dev/input/event1234,bus=pci.0,\
 addr=0x12,iommu_platform=on,ats=on \
--device virtio-gpu-pci,id=video0,bus=pci.0,addr=0x2,iommu_platform=on,ats=on \
+-chardev socket,id=chr-vu-video0,fd=0 \
+-device vhost-user-gpu-pci,id=video0,max_outputs=1,chardev=chr-vu-video0,\
+bus=pci.0,addr=0x2,iommu_platform=on,ats=on \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0xc,iommu_platform=on,\
 ats=on \
 -object rng-random,id=objrng0,filename=/dev/random \
-- 
2.23.0




More information about the libvir-list mailing list