[libvirt] [PATCH v3 0/8] Enable vfio-pci 'property' for mediated device

RFC here: https://www.redhat.com/archives/libvir-list/2018-May/msg02218.html Since v1 [1]: - remodeled egl-headless to be a standalone graphics element instead of a result of some automagic with graphic's <gl> element - pushed the first 5 simple fixes that were RB'd - fixed some nits raised during review Since v2 [2] - converted the 'display' and 'egl-headless' PostParse callbacks in patches 2 and 6 to Validate callbacks as they should have been since the beginning (see the RFC) - some minor nits - added a standalone patch substituting some 'error' labels with 'cleanup' as requested during review [1] https://www.redhat.com/archives/libvir-list/2018-June/msg01740.html [2] https://www.redhat.com/archives/libvir-list/2018-July/msg00485.html Erik Skultety (8): qemu: caps: Introduce a capability for egl-headless conf: Introduce a new graphics display type 'headless' qemu: caps: Add vfio-pci.display capability conf: Introduce virDomainGraphicsDefHasOpenGL helper conf: Replace 'error' with 'cleanup' in virDomainHostdevDefParseXMLSubsys conf: Introduce new <hostdev> attribute 'display' qemu: command: Enable formatting vfio-pci.display option onto cmdline docs: Update news about the VNC console enablement for mdevs docs/formatdomain.html.in | 53 +++++++++- docs/news.xml | 10 ++ docs/schemas/domaincommon.rng | 8 ++ src/conf/domain_conf.c | 106 ++++++++++++++++---- src/conf/domain_conf.h | 5 + src/libvirt_private.syms | 1 + src/libxl/libxl_conf.c | 1 + src/qemu/qemu_capabilities.c | 10 ++ src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_command.c | 60 +++++++++++- src/qemu/qemu_domain.c | 107 ++++++++++++++++++++- src/qemu/qemu_driver.c | 2 + src/qemu/qemu_hotplug.c | 1 + src/qemu/qemu_process.c | 4 + src/vmx/vmx.c | 1 + tests/domaincapsschemadata/full.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 2 + tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 2 + tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 2 + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 2 + tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 2 + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 2 + tests/qemuxml2argvdata/graphics-egl-headless.args | 26 +++++ tests/qemuxml2argvdata/graphics-egl-headless.xml | 31 ++++++ .../qemuxml2argvdata/graphics-sdl-egl-headless.xml | 35 +++++++ .../graphics-spice-egl-headless.args | 31 ++++++ .../graphics-spice-egl-headless.xml | 36 +++++++ .../graphics-spice-invalid-egl-headless.xml | 37 +++++++ .../graphics-vnc-egl-headless.args | 28 ++++++ .../qemuxml2argvdata/graphics-vnc-egl-headless.xml | 37 +++++++ .../hostdev-mdev-display-missing-graphics.xml | 35 +++++++ .../hostdev-mdev-display-spice-egl-headless.args | 32 ++++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 ++++++++ .../hostdev-mdev-display-spice-opengl.args | 31 ++++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++++ .../hostdev-mdev-display-vnc-egl-headless.args | 32 ++++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 ++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.args | 31 ++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++++ tests/qemuxml2argvdata/hostdev-mdev-display.xml | 39 ++++++++ tests/qemuxml2argvtest.c | 48 +++++++++ .../graphics-spice-egl-headless.xml | 44 +++++++++ .../graphics-vnc-egl-headless.xml | 42 ++++++++ .../hostdev-mdev-display-active.xml | 47 +++++++++ tests/qemuxml2xmltest.c | 4 + 50 files changed, 1168 insertions(+), 29 deletions(-) create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-spice-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-vnc-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display.xml create mode 100644 tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml create mode 100644 tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display-active.xml -- 2.14.4

Since QEMU 2.10, it's possible to use a new type of display - egl-headless which uses drm nodes to provide OpenGL support. This patch adds a capability for that. However, since QEMU doesn't provide a QMP command to probe it, we have to base the capability on specific QEMU version. Signed-off-by: Erik Skultety <eskultet@redhat.com> Acked-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_capabilities.c | 6 ++++++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 1 + 13 files changed, 18 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 23b483349f..df358f8967 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -503,6 +503,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "machine.pseries.cap-hpt-max-page-size", "machine.pseries.cap-htm", "usb-storage.werror", + "egl-headless", ); @@ -4030,6 +4031,11 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); } + /* '-display egl-headless' cmdline option is supported since QEMU 2.10, but + * there's no way to probe it */ + if (qemuCaps->version >= 2010000) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_EGL_HEADLESS); + /* no way to query for -numa dist */ if (qemuCaps->version >= 2010000) virQEMUCapsSet(qemuCaps, QEMU_CAPS_NUMA_DIST); diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 1fa0ebfea3..55221e7e57 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -487,6 +487,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE, /* -machine pseries.cap-hpt-max-page-size */ QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, /* -machine pseries.cap-htm */ QEMU_CAPS_USB_STORAGE_WERROR, /* -device usb-storage,werror=..,rerror=.. */ + QEMU_CAPS_EGL_HEADLESS, /* -display egl-headless */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml index 169641063c..a70e050765 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml @@ -159,6 +159,7 @@ <flag name='hda-output'/> <flag name='blockdev-del'/> <flag name='vhost-vsock'/> + <flag name='egl-headless'/> <version>2010000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>307647</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml index 92c095abd2..72709905d8 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml @@ -158,6 +158,7 @@ <flag name='hda-output'/> <flag name='blockdev-del'/> <flag name='vhost-vsock'/> + <flag name='egl-headless'/> <version>2010000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>386992</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml index 5e22e21224..7347f5683f 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml @@ -119,6 +119,7 @@ <flag name='sdl-gl'/> <flag name='blockdev-del'/> <flag name='vhost-vsock'/> + <flag name='egl-headless'/> <version>2010000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>307899</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml index 10b066bff1..d69a148cd2 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml @@ -203,6 +203,7 @@ <flag name='vmgenid'/> <flag name='vhost-vsock'/> <flag name='mch'/> + <flag name='egl-headless'/> <version>2010000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>367995</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml index 6ca2e57ef8..b359f9a049 100644 --- a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml @@ -126,6 +126,7 @@ <flag name='blockdev-del'/> <flag name='vhost-vsock'/> <flag name='tpm-emulator'/> + <flag name='egl-headless'/> <version>2011000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>346751</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml index ecc029f403..80e7afec04 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml @@ -169,6 +169,7 @@ <flag name='vhost-vsock'/> <flag name='chardev-fd-pass'/> <flag name='tpm-emulator'/> + <flag name='egl-headless'/> <version>2011090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>347550</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml index 7139179304..c4b09c0003 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml @@ -167,6 +167,7 @@ <flag name='chardev-fd-pass'/> <flag name='tpm-emulator'/> <flag name='machine.pseries.cap-htm'/> + <flag name='egl-headless'/> <version>2011090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>428334</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml index 87d189e58d..1ff2fe45e1 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml @@ -133,6 +133,7 @@ <flag name='vhost-vsock'/> <flag name='chardev-fd-pass'/> <flag name='tpm-emulator'/> + <flag name='egl-headless'/> <version>2012000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>375999</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml index 9c1f6c327c..37d17786cf 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml @@ -211,6 +211,7 @@ <flag name='mch'/> <flag name='mch.extended-tseg-mbytes'/> <flag name='sev-guest'/> + <flag name='egl-headless'/> <version>2011090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>416196</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml index 33cd00e613..57bf5dba11 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml @@ -167,6 +167,7 @@ <flag name='tpm-emulator'/> <flag name='machine.pseries.cap-hpt-max-page-size'/> <flag name='machine.pseries.cap-htm'/> + <flag name='egl-headless'/> <version>2012050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>446771</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml index d7c25c65dd..d87e11564f 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml @@ -210,6 +210,7 @@ <flag name='mch.extended-tseg-mbytes'/> <flag name='sev-guest'/> <flag name='usb-storage.werror'/> + <flag name='egl-headless'/> <version>2012050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>437827</microcodeVersion> -- 2.14.4

On Wed, Jul 11, 2018 at 03:58:21PM +0200, Erik Skultety wrote:
Since QEMU 2.10, it's possible to use a new type of display - egl-headless which uses drm nodes to provide OpenGL support. This patch adds a capability for that. However, since QEMU doesn't provide a QMP command to probe it, we have to base the capability on specific QEMU version.
Signed-off-by: Erik Skultety <eskultet@redhat.com> Acked-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_capabilities.c | 6 ++++++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 1 + 13 files changed, 18 insertions(+)
Sigh. Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Since 2.10 QEMU supports a new display type egl-headless which uses the drm nodes for OpenGL rendering copying back the rendered bits back to QEMU into a dma-buf which can be accessed by standard "display" apps like VNC or SPICE. Although this display type can be used on its own, for any practical use case it makes sense to pair it with either VNC or SPICE display. The clear benefit of this display is that VNC gains OpenGL support, which it natively doesn't have, and SPICE gains remote OpenGL support (native OpenGL support only works locally through a UNIX socket, i.e. listen type=socket/none) Signed-off-by: Erik Skultety <eskultet@redhat.com> --- docs/formatdomain.html.in | 33 +++++++++++++- docs/schemas/domaincommon.rng | 3 ++ src/conf/domain_conf.c | 6 ++- src/conf/domain_conf.h | 1 + src/libxl/libxl_conf.c | 1 + src/qemu/qemu_command.c | 35 ++++++++++++++- src/qemu/qemu_domain.c | 52 +++++++++++++++++++++- src/qemu/qemu_driver.c | 2 + src/qemu/qemu_hotplug.c | 1 + src/qemu/qemu_process.c | 4 ++ src/vmx/vmx.c | 1 + tests/domaincapsschemadata/full.xml | 1 + tests/qemuxml2argvdata/graphics-egl-headless.args | 26 +++++++++++ tests/qemuxml2argvdata/graphics-egl-headless.xml | 31 +++++++++++++ .../qemuxml2argvdata/graphics-sdl-egl-headless.xml | 35 +++++++++++++++ .../graphics-spice-egl-headless.args | 31 +++++++++++++ .../graphics-spice-egl-headless.xml | 36 +++++++++++++++ .../graphics-spice-invalid-egl-headless.xml | 37 +++++++++++++++ .../graphics-vnc-egl-headless.args | 28 ++++++++++++ .../qemuxml2argvdata/graphics-vnc-egl-headless.xml | 37 +++++++++++++++ tests/qemuxml2argvtest.c | 17 +++++++ .../graphics-spice-egl-headless.xml | 44 ++++++++++++++++++ .../graphics-vnc-egl-headless.xml | 42 +++++++++++++++++ tests/qemuxml2xmltest.c | 2 + 24 files changed, 501 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-spice-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-vnc-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml create mode 100644 tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml create mode 100644 tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index a3afe137bf..9dd22554ad 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6299,7 +6299,8 @@ qemu-kvm -net nic,model=? /dev/null <p> The <code>graphics</code> element has a mandatory <code>type</code> attribute which takes the value <code>sdl</code>, <code>vnc</code>, - <code>spice</code>, <code>rdp</code> or <code>desktop</code>: + <code>spice</code>, <code>rdp</code>, <code>desktop</code> or + <code>egl-headless</code>: </p> <dl> <dt><code>sdl</code></dt> @@ -6358,6 +6359,11 @@ qemu-kvm -net nic,model=? /dev/null auto-allocation and <code>autoport</code> having no effect due to security reasons) <span class="since">Since 1.0.6</span>. </p> + <p> + Although VNC doesn't support OpenGL natively, it can be paired + with graphics type <code>egl-headless</code> (see below) which + will instruct QEMU to open and use drm nodes for OpenGL rendering. + </p> </dd> <dt><code>spice</code> <span class="since">Since 0.8.6</span></dt> <dd> @@ -6463,6 +6469,12 @@ qemu-kvm -net nic,model=? /dev/null You can enable or disable OpenGL support explicitly with the <code>gl</code> element, by setting the <code>enable</code> property. (QEMU only, <span class="since">since 1.3.3</span>). + Note that this only works locally, since this requires usage of + UNIX sockets, i.e. using <code>listen</code> types 'socket' or + 'none'. For accelerated OpenGL with remote support, consider + pairing this element with type <code>egl-headless</code> + (see below). However, this will deliver weaker performance + compared to native Spice OpenGL support. </p> <p> By default, QEMU will pick the first available GPU DRM render node. @@ -6498,6 +6510,25 @@ qemu-kvm -net nic,model=? /dev/null <code>fullscreen</code>. </p> </dd> + <dt><code>egl-headless</code><span class="since">Since 4.6.0</span></dt> + <dd> + <p> + This display type provides support for an OpenGL accelerated + display accessible both locally and remotely (for comparison, + Spice's native OpenGL support only works locally using UNIX + sockets at the moment, but has better performance). Since this + display type doesn't provide any window or graphical console like + the other types, for practical reasons it should be paired with + either <code>vnc</code> or <code>spice</code> graphics types. + This display type is only supported by QEMU domains + (needs QEMU <span class="since">2.10</span> or newer) and doesn't + accept any attributes. + </p> + <pre> +<graphics type='spice' autoport='yes'/> +<graphics type='egl-headless'/> + </pre> + </dd> </dl> </dd> </dl> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index bd687ce9d3..8f7d273d9f 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3366,6 +3366,9 @@ </attribute> </optional> </group> + <attribute name="type"> + <value>egl-headless</value> + </attribute> </choice> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7396616eda..89c6556026 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -615,7 +615,8 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST, "vnc", "rdp", "desktop", - "spice") + "spice", + "egl-headless") VIR_ENUM_IMPL(virDomainGraphicsListen, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST, "none", @@ -1426,6 +1427,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) virDomainGraphicsAuthDefClear(&def->data.spice.auth); break; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } @@ -14162,6 +14164,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, if (virDomainGraphicsDefParseXMLSpice(def, node, ctxt, flags) < 0) goto error; break; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } @@ -26394,6 +26397,7 @@ virDomainGraphicsDefFormat(virBufferPtr buf, virDomainGraphicsAuthDefFormatAttr(buf, &def->data.spice.auth, flags); break; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 0f10e242fd..26f75b15d0 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1473,6 +1473,7 @@ typedef enum { VIR_DOMAIN_GRAPHICS_TYPE_RDP, VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP, VIR_DOMAIN_GRAPHICS_TYPE_SPICE, + VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS, VIR_DOMAIN_GRAPHICS_TYPE_LAST } virDomainGraphicsType; diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 452a77f3b8..cda4eb9d31 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1441,6 +1441,7 @@ libxlMakeVfb(virPortAllocatorRangePtr graphicsports, case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 44ae8dcef7..48e224cabc 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8213,6 +8213,27 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, return -1; } + +static int +qemuBuildGraphicsHeadlessCommandLine(virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED, + virCommandPtr cmd, + virQEMUCapsPtr qemuCaps, + virDomainGraphicsDefPtr def ATTRIBUTE_UNUSED) +{ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_EGL_HEADLESS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("egl-headless display is not supported with this " + "QEMU binary")); + return -1; + } + + virCommandAddArg(cmd, "-display"); + virCommandAddArg(cmd, "egl-headless"); + + return 0; +} + + static int qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, virCommandPtr cmd, @@ -8242,6 +8263,12 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, qemuCaps, graphics) < 0) return -1; + break; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: + if (qemuBuildGraphicsHeadlessCommandLine(cfg, cmd, + qemuCaps, graphics) < 0) + return -1; + break; case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: @@ -10069,6 +10096,7 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver, int sdl = 0; int vnc = 0; int spice = 0; + int egl_headless = 0; if (!virQEMUDriverIsPrivileged(driver)) { /* If we have no cgroups then we can have no tunings that @@ -10110,6 +10138,9 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver, case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: ++spice; break; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: + ++egl_headless; + break; case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: @@ -10117,10 +10148,10 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver, } } - if (sdl > 1 || vnc > 1 || spice > 1) { + if (sdl > 1 || vnc > 1 || spice > 1 || egl_headless > 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("only 1 graphics device of each type " - "(sdl, vnc, spice) is supported")); + "(sdl, vnc, spice, headless) is supported")); return -1; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ed76495309..5da8c8bfcc 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5528,6 +5528,53 @@ qemuDomainDeviceDefValidateTPM(virDomainTPMDef *tpm, } +static int +qemuDomainDeviceDefValidateGraphics(const virDomainGraphicsDef *graphics, + const virDomainDef *def) +{ + bool have_egl_headless = false; + size_t i; + + /* are we running with egl-headless? */ + for (i = 0; i < def->ngraphics; i++) { + graphics = def->graphics[i]; + + if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS) { + have_egl_headless = true; + break; + } + } + + /* Only VNC and SPICE can be paired with egl-headless, the other types + * either don't make sense to pair with egl-headless or aren't even + * supported by QEMU. + */ + if (have_egl_headless) { + if (graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS && + graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC && + graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("graphics type 'egl-headless' is only supported " + "with one of: 'vnc', 'spice' graphics types")); + return -1; + } + + /* '-spice gl=on' and '-display egl-headless' are mutually + * exclusive + */ + if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE && + graphics->data.spice.gl == VIR_TRISTATE_BOOL_YES) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("multiple OpenGL displays are not supported " + "by QEMU")); + return -1; + } + } + + return 0; +} + + static int qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, const virDomainDef *def, @@ -5595,11 +5642,14 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, ret = qemuDomainDeviceDefValidateTPM(dev->data.tpm, def); break; + case VIR_DOMAIN_DEVICE_GRAPHICS: + ret = qemuDomainDeviceDefValidateGraphics(dev->data.graphics, def); + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: - case VIR_DOMAIN_DEVICE_GRAPHICS: case VIR_DOMAIN_DEVICE_HUB: case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5de9aaefbb..16f0087bc2 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -18104,6 +18104,7 @@ qemuDomainOpenGraphics(virDomainPtr dom, case VIR_DOMAIN_GRAPHICS_TYPE_SDL: case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Can only open VNC or SPICE graphics backends, not %s"), virDomainGraphicsTypeToString(vm->def->graphics[idx]->type)); @@ -18172,6 +18173,7 @@ qemuDomainOpenGraphicsFD(virDomainPtr dom, case VIR_DOMAIN_GRAPHICS_TYPE_SDL: case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Can only open VNC or SPICE graphics backends, not %s"), virDomainGraphicsTypeToString(vm->def->graphics[idx]->type)); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 3dfa51b0a0..66bc7f9f27 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3694,6 +3694,7 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver, case VIR_DOMAIN_GRAPHICS_TYPE_SDL: case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: virReportError(VIR_ERR_INTERNAL_ERROR, _("unable to change config on '%s' graphics type"), type); break; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index c903a8e5c8..a4b1f97df5 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4467,6 +4467,7 @@ qemuProcessGraphicsReservePorts(virDomainGraphicsDefPtr graphics, case VIR_DOMAIN_GRAPHICS_TYPE_SDL: case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } @@ -4505,6 +4506,7 @@ qemuProcessGraphicsAllocatePorts(virQEMUDriverPtr driver, case VIR_DOMAIN_GRAPHICS_TYPE_SDL: case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } @@ -4657,6 +4659,7 @@ qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver, case VIR_DOMAIN_GRAPHICS_TYPE_SDL: case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } @@ -4944,6 +4947,7 @@ qemuProcessStartValidateGraphics(virDomainObjPtr vm) case VIR_DOMAIN_GRAPHICS_TYPE_SDL: case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: case VIR_DOMAIN_GRAPHICS_TYPE_LAST: break; } diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index fe24b060d7..937bf0c96b 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -3282,6 +3282,7 @@ virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virDomainDe case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported graphics type '%s'"), virDomainGraphicsTypeToString(def->graphics[i]->type)); diff --git a/tests/domaincapsschemadata/full.xml b/tests/domaincapsschemadata/full.xml index d3faf38da0..154c4a6fe9 100644 --- a/tests/domaincapsschemadata/full.xml +++ b/tests/domaincapsschemadata/full.xml @@ -59,6 +59,7 @@ <value>rdp</value> <value>desktop</value> <value>spice</value> + <value>egl-headless</value> </enum> </graphics> <video supported='yes'> diff --git a/tests/qemuxml2argvdata/graphics-egl-headless.args b/tests/qemuxml2argvdata/graphics-egl-headless.args new file mode 100644 index 0000000000..fdf540ddfc --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-egl-headless.args @@ -0,0 +1,26 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-display egl-headless \ +-vga cirrus diff --git a/tests/qemuxml2argvdata/graphics-egl-headless.xml b/tests/qemuxml2argvdata/graphics-egl-headless.xml new file mode 100644 index 0000000000..7b001cd2eb --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-egl-headless.xml @@ -0,0 +1,31 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='egl-headless'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml b/tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml new file mode 100644 index 0000000000..955dfeb3c2 --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml @@ -0,0 +1,35 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='sdl' display=':0.1' xauth='/root/.Xauthority'/> + <graphics type='egl-headless'/> + <video> + <model type='vga' vram='16384' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/graphics-spice-egl-headless.args b/tests/qemuxml2argvdata/graphics-spice-egl-headless.args new file mode 100644 index 0000000000..4886ee05f6 --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-spice-egl-headless.args @@ -0,0 +1,31 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-spice port=5903,addr=127.0.0.1 \ +-display egl-headless \ +-vga qxl \ +-global qxl-vga.ram_size=67108864 \ +-global qxl-vga.vram_size=33554432 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/graphics-spice-egl-headless.xml b/tests/qemuxml2argvdata/graphics-spice-egl-headless.xml new file mode 100644 index 0000000000..fafae13a0f --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-spice-egl-headless.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='spice' port='5903' autoport='no' listen='127.0.0.1'> + <listen type='address' address='127.0.0.1'/> + </graphics> + <graphics type='egl-headless'/> + <video> + <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/> + </video> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml b/tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml new file mode 100644 index 0000000000..25ae61cef6 --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='spice'> + <listen type='none'/> + <gl enable='yes'/> + </graphics> + <graphics type='egl-headless'/> + <video> + <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/> + </video> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/graphics-vnc-egl-headless.args b/tests/qemuxml2argvdata/graphics-vnc-egl-headless.args new file mode 100644 index 0000000000..2d2b3cf0fb --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-vnc-egl-headless.args @@ -0,0 +1,28 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-vnc '[2001:1:2:3:4:5:1234:1234]:3' \ +-display egl-headless \ +-vga cirrus diff --git a/tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml b/tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml new file mode 100644 index 0000000000..570cf2e50f --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='vnc' port='5903' autoport='no' listen='2001:1:2:3:4:5:1234:1234'> + <listen type='address' address='2001:1:2:3:4:5:1234:1234'/> + </graphics> + <graphics type='egl-headless'/> + <video> + <model type='cirrus' vram='16384' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index a929e4314e..6014c81802 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1166,6 +1166,10 @@ mymain(void) DO_TEST_PARSE_ERROR("disk-scsi-incompatible-address", QEMU_CAPS_VIRTIO_SCSI); + DO_TEST("graphics-egl-headless", + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_CIRRUS_VGA); + DO_TEST("graphics-vnc", QEMU_CAPS_VNC, QEMU_CAPS_DEVICE_CIRRUS_VGA); DO_TEST("graphics-vnc-socket", QEMU_CAPS_VNC, QEMU_CAPS_DEVICE_CIRRUS_VGA); DO_TEST("graphics-vnc-websocket", QEMU_CAPS_VNC, QEMU_CAPS_VNC_WEBSOCKET, @@ -1197,9 +1201,14 @@ mymain(void) driver.config->vncSASL = driver.config->vncTLSx509verify = driver.config->vncTLS = 0; VIR_FREE(driver.config->vncSASLdir); VIR_FREE(driver.config->vncTLSx509certdir); + DO_TEST("graphics-vnc-egl-headless", + QEMU_CAPS_VNC, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_CIRRUS_VGA); DO_TEST("graphics-sdl", QEMU_CAPS_DEVICE_VGA); + DO_TEST_FAILURE("graphics-sdl-egl-headless", NONE); DO_TEST("graphics-sdl-fullscreen", QEMU_CAPS_DEVICE_CIRRUS_VGA); DO_TEST("graphics-spice", @@ -1254,6 +1263,14 @@ mymain(void) QEMU_CAPS_SPICE_UNIX, QEMU_CAPS_DEVICE_CIRRUS_VGA); driver.config->spiceAutoUnixSocket = false; + DO_TEST("graphics-spice-egl-headless", + QEMU_CAPS_SPICE, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_QXL); + DO_TEST_FAILURE("graphics-spice-invalid-egl-headless", + QEMU_CAPS_SPICE, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_QXL); DO_TEST("input-usbmouse", NONE); DO_TEST("input-usbtablet", NONE); diff --git a/tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml b/tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml new file mode 100644 index 0000000000..6d96264914 --- /dev/null +++ b/tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml @@ -0,0 +1,44 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='spice' port='5903' autoport='no' listen='127.0.0.1'> + <listen type='address' address='127.0.0.1'/> + </graphics> + <graphics type='egl-headless'/> + <video> + <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml b/tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml new file mode 100644 index 0000000000..4155c10397 --- /dev/null +++ b/tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml @@ -0,0 +1,42 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='vnc' port='5903' autoport='no' listen='2001:1:2:3:4:5:1234:1234'> + <listen type='address' address='2001:1:2:3:4:5:1234:1234'/> + </graphics> + <graphics type='egl-headless'/> + <video> + <model type='cirrus' vram='16384' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index c0b228515c..3527ccdec3 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -415,6 +415,7 @@ mymain(void) cfg->vncAutoUnixSocket = false; DO_TEST("graphics-vnc-socket", NONE); DO_TEST("graphics-vnc-auto-socket", NONE); + DO_TEST("graphics-vnc-egl-headless", NONE); DO_TEST("graphics-sdl", NONE); DO_TEST("graphics-sdl-fullscreen", NONE); @@ -426,6 +427,7 @@ mymain(void) cfg->spiceAutoUnixSocket = true; DO_TEST("graphics-spice-auto-socket-cfg", NONE); cfg->spiceAutoUnixSocket = false; + DO_TEST("graphics-spice-egl-headless", NONE); DO_TEST("input-usbmouse", NONE); DO_TEST("input-usbtablet", NONE); -- 2.14.4

s/conf/qemu/ in the commit summary, since you chose to group the XML parser and the QEMU driver changes in one commit. On Wed, Jul 11, 2018 at 03:58:22PM +0200, Erik Skultety wrote:
Since 2.10 QEMU supports a new display type egl-headless which uses the drm nodes for OpenGL rendering copying back the rendered bits back to QEMU into a dma-buf which can be accessed by standard "display" apps like VNC or SPICE. Although this display type can be used on its own, for any practical use case it makes sense to pair it with either VNC or SPICE display. The clear benefit of this display is that VNC gains OpenGL support, which it natively doesn't have, and SPICE gains remote OpenGL support (native OpenGL support only works locally through a UNIX socket, i.e. listen type=socket/none)
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- docs/formatdomain.html.in | 33 +++++++++++++- docs/schemas/domaincommon.rng | 3 ++ src/conf/domain_conf.c | 6 ++- src/conf/domain_conf.h | 1 + src/libxl/libxl_conf.c | 1 + src/qemu/qemu_command.c | 35 ++++++++++++++- src/qemu/qemu_domain.c | 52 +++++++++++++++++++++- src/qemu/qemu_driver.c | 2 + src/qemu/qemu_hotplug.c | 1 + src/qemu/qemu_process.c | 4 ++ src/vmx/vmx.c | 1 + tests/domaincapsschemadata/full.xml | 1 + tests/qemuxml2argvdata/graphics-egl-headless.args | 26 +++++++++++ tests/qemuxml2argvdata/graphics-egl-headless.xml | 31 +++++++++++++ .../qemuxml2argvdata/graphics-sdl-egl-headless.xml | 35 +++++++++++++++ .../graphics-spice-egl-headless.args | 31 +++++++++++++ .../graphics-spice-egl-headless.xml | 36 +++++++++++++++ .../graphics-spice-invalid-egl-headless.xml | 37 +++++++++++++++ .../graphics-vnc-egl-headless.args | 28 ++++++++++++ .../qemuxml2argvdata/graphics-vnc-egl-headless.xml | 37 +++++++++++++++ tests/qemuxml2argvtest.c | 17 +++++++ .../graphics-spice-egl-headless.xml | 44 ++++++++++++++++++ .../graphics-vnc-egl-headless.xml | 42 +++++++++++++++++ tests/qemuxml2xmltest.c | 2 + 24 files changed, 501 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-sdl-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-spice-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-spice-invalid-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/graphics-vnc-egl-headless.args create mode 100644 tests/qemuxml2argvdata/graphics-vnc-egl-headless.xml create mode 100644 tests/qemuxml2xmloutdata/graphics-spice-egl-headless.xml create mode 100644 tests/qemuxml2xmloutdata/graphics-vnc-egl-headless.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 44ae8dcef7..48e224cabc 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8213,6 +8213,27 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, return -1; }
+ +static int +qemuBuildGraphicsHeadlessCommandLine(virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED, + virCommandPtr cmd, + virQEMUCapsPtr qemuCaps, + virDomainGraphicsDefPtr def ATTRIBUTE_UNUSED)
These arguments are unused now as well as at the end of the series and can be dropped.
+{ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_EGL_HEADLESS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("egl-headless display is not supported with this " + "QEMU binary")); + return -1; + } +
This belongs in qemu.*Validate.
+ virCommandAddArg(cmd, "-display"); + virCommandAddArg(cmd, "egl-headless"); + + return 0; +} + + static int qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, virCommandPtr cmd, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ed76495309..5da8c8bfcc 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5528,6 +5528,53 @@ qemuDomainDeviceDefValidateTPM(virDomainTPMDef *tpm, }
+static int +qemuDomainDeviceDefValidateGraphics(const virDomainGraphicsDef *graphics, + const virDomainDef *def) +{ + bool have_egl_headless = false; + size_t i; + + /* are we running with egl-headless? */
The variable name is self-explanatory, no need to explain the for cycle here.
+ for (i = 0; i < def->ngraphics; i++) { + graphics = def->graphics[i]; + + if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS) { + have_egl_headless = true; + break; + } + } + + /* Only VNC and SPICE can be paired with egl-headless, the other types + * either don't make sense to pair with egl-headless or aren't even + * supported by QEMU. + */ + if (have_egl_headless) { + if (graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS && + graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC && + graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("graphics type 'egl-headless' is only supported " + "with one of: 'vnc', 'spice' graphics types")); + return -1; + } + + /* '-spice gl=on' and '-display egl-headless' are mutually + * exclusive + */ + if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE && + graphics->data.spice.gl == VIR_TRISTATE_BOOL_YES) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("multiple OpenGL displays are not supported " + "by QEMU")); + return -1; + } + } + + return 0; +} + + static int qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, const virDomainDef *def,
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

QEMU 2.12 introduced a new vfio-pci device option 'display=on/off/auto'. This patch introduces the necessary capability. Signed-off-by: Erik Skultety <eskultet@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 1 + 8 files changed, 13 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index df358f8967..0fb800589a 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -504,6 +504,9 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "machine.pseries.cap-htm", "usb-storage.werror", "egl-headless", + + /* 315 */ + "vfio-pci.display", ); @@ -1197,6 +1200,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsPCIAssign[] = { static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVfioPCI[] = { { "bootindex", QEMU_CAPS_VFIO_PCI_BOOTINDEX }, + { "display", QEMU_CAPS_VFIO_PCI_DISPLAY }, }; static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsSCSIDisk[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 55221e7e57..9e8ad5f5c3 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -489,6 +489,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_USB_STORAGE_WERROR, /* -device usb-storage,werror=..,rerror=.. */ QEMU_CAPS_EGL_HEADLESS, /* -display egl-headless */ + /* 315 */ + QEMU_CAPS_VFIO_PCI_DISPLAY, /* -device vfio-pci.display */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml index 80e7afec04..0cc6327573 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml @@ -170,6 +170,7 @@ <flag name='chardev-fd-pass'/> <flag name='tpm-emulator'/> <flag name='egl-headless'/> + <flag name='vfio-pci.display'/> <version>2011090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>347550</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml index c4b09c0003..a88da6193e 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml @@ -168,6 +168,7 @@ <flag name='tpm-emulator'/> <flag name='machine.pseries.cap-htm'/> <flag name='egl-headless'/> + <flag name='vfio-pci.display'/> <version>2011090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>428334</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml index 1ff2fe45e1..7121da27a0 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml @@ -134,6 +134,7 @@ <flag name='chardev-fd-pass'/> <flag name='tpm-emulator'/> <flag name='egl-headless'/> + <flag name='vfio-pci.display'/> <version>2012000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>375999</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml index 37d17786cf..78889facce 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml @@ -212,6 +212,7 @@ <flag name='mch.extended-tseg-mbytes'/> <flag name='sev-guest'/> <flag name='egl-headless'/> + <flag name='vfio-pci.display'/> <version>2011090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>416196</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml index 57bf5dba11..01bb968938 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml @@ -168,6 +168,7 @@ <flag name='machine.pseries.cap-hpt-max-page-size'/> <flag name='machine.pseries.cap-htm'/> <flag name='egl-headless'/> + <flag name='vfio-pci.display'/> <version>2012050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>446771</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml index d87e11564f..56b1556bb3 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml @@ -211,6 +211,7 @@ <flag name='sev-guest'/> <flag name='usb-storage.werror'/> <flag name='egl-headless'/> + <flag name='vfio-pci.display'/> <version>2012050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>437827</microcodeVersion> -- 2.14.4

On Wed, Jul 11, 2018 at 03:58:23PM +0200, Erik Skultety wrote:
QEMU 2.12 introduced a new vfio-pci device option 'display=on/off/auto'. This patch introduces the necessary capability.
Signed-off-by: Erik Skultety <eskultet@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 1 + 8 files changed, 13 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

A simple helper which will loop through all the graphics elements and checks whether at least one of them enables OpenGL support, either by containing <gl enable='yes'/> or being of type 'egl-headless'. Signed-off-by: Erik Skultety <eskultet@redhat.com> Acked-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 3 +++ src/libvirt_private.syms | 1 + 3 files changed, 47 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 89c6556026..187a8b36a0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -30274,3 +30274,46 @@ virDomainDefHasManagedPR(const virDomainDef *def) return false; } + + +/** + * virDomainGraphicsDefHasOpenGL: + * @def: domain definition + * + * Returns true if a domain config contains at least one <graphics> element + * with OpenGL support enabled, false otherwise. + */ +bool +virDomainGraphicsDefHasOpenGL(const virDomainDef *def) +{ + size_t i; + + for (i = 0; i < def->ngraphics; i++) { + virDomainGraphicsDefPtr graphics = def->graphics[i]; + + /* we only care about OpenGL support for a given type here */ + switch (graphics->type) { + case VIR_DOMAIN_GRAPHICS_TYPE_VNC: + case VIR_DOMAIN_GRAPHICS_TYPE_RDP: + case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + continue; + case VIR_DOMAIN_GRAPHICS_TYPE_SDL: + if (graphics->data.sdl.gl == VIR_TRISTATE_BOOL_YES) + return true; + + continue; + case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: + if (graphics->data.spice.gl == VIR_TRISTATE_BOOL_YES) + return true; + + continue; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: + return true; + + case VIR_DOMAIN_GRAPHICS_TYPE_LAST: + break; + } + } + + return false; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 26f75b15d0..3deda1d978 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3642,4 +3642,7 @@ virDomainDiskGetDetectZeroesMode(virDomainDiskDiscard discard, bool virDomainDefHasManagedPR(const virDomainDef *def); +bool +virDomainGraphicsDefHasOpenGL(const virDomainDef *def); + #endif /* __DOMAIN_CONF_H */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e688981c3e..9f460d7740 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -359,6 +359,7 @@ virDomainGetFilesystemForTarget; virDomainGraphicsAuthConnectedTypeFromString; virDomainGraphicsAuthConnectedTypeToString; virDomainGraphicsDefFree; +virDomainGraphicsDefHasOpenGL; virDomainGraphicsGetListen; virDomainGraphicsListenAppendAddress; virDomainGraphicsListenAppendSocket; -- 2.14.4

On Wed, Jul 11, 2018 at 03:58:24PM +0200, Erik Skultety wrote:
A simple helper which will loop through all the graphics elements and checks whether at least one of them enables OpenGL support, either by containing <gl enable='yes'/> or being of type 'egl-headless'.
Signed-off-by: Erik Skultety <eskultet@redhat.com> Acked-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 3 +++ src/libvirt_private.syms | 1 + 3 files changed, 47 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The exit path is the same for both success and failure, so the label should be called cleanup. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/conf/domain_conf.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 187a8b36a0..8deff5442f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7680,18 +7680,18 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unknown host device source address type '%s'"), type); - goto error; + goto cleanup; } } else { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing source address type")); - goto error; + goto cleanup; } if (!(sourcenode = virXPathNode("./source", ctxt))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing <source> element in hostdev device")); - goto error; + goto cleanup; } if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB && @@ -7699,20 +7699,20 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Setting startupPolicy is only allowed for USB" " devices")); - goto error; + goto cleanup; } if (sgio) { if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) { virReportError(VIR_ERR_XML_ERROR, "%s", _("sgio is only supported for scsi host device")); - goto error; + goto cleanup; } if ((scsisrc->sgio = virDomainDeviceSGIOTypeFromString(sgio)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unknown sgio mode '%s'"), sgio); - goto error; + goto cleanup; } } @@ -7720,14 +7720,14 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) { virReportError(VIR_ERR_XML_ERROR, "%s", _("rawio is only supported for scsi host device")); - goto error; + goto cleanup; } if ((scsisrc->rawio = virTristateBoolTypeFromString(rawio)) <= 0) { virReportError(VIR_ERR_XML_ERROR, _("unknown hostdev rawio setting '%s'"), rawio); - goto error; + goto cleanup; } } @@ -7736,28 +7736,28 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, virReportError(VIR_ERR_XML_ERROR, "%s", _("'model' attribute in <hostdev> is only supported " "when type='mdev'")); - goto error; + goto cleanup; } } else { if (!model) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'model' attribute in mediated device's " "<hostdev> element")); - goto error; + goto cleanup; } if ((mdevsrc->model = virMediatedDeviceModelTypeFromString(model)) < 0) { virReportError(VIR_ERR_XML_ERROR, _("unknown hostdev model '%s'"), model); - goto error; + goto cleanup; } } switch (def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: if (virDomainHostdevSubsysPCIDefParseXML(sourcenode, def, flags) < 0) - goto error; + goto cleanup; backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT; if ((backendStr = virXPathString("string(./driver/@name)", ctxt)) && @@ -7766,7 +7766,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown PCI device <driver name='%s'/> " "has been specified"), backendStr); - goto error; + goto cleanup; } pcisrc->backend = backend; @@ -7774,32 +7774,32 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: if (virDomainHostdevSubsysUSBDefParseXML(sourcenode, def) < 0) - goto error; + goto cleanup; break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: if (virDomainHostdevSubsysSCSIDefParseXML(sourcenode, scsisrc, ctxt) < 0) - goto error; + goto cleanup; break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: if (virDomainHostdevSubsysSCSIVHostDefParseXML(sourcenode, def) < 0) - goto error; + goto cleanup; break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: if (virDomainHostdevSubsysMediatedDevDefParseXML(def, ctxt) < 0) - goto error; + goto cleanup; break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("address type='%s' not supported in hostdev interfaces"), virDomainHostdevSubsysTypeToString(def->source.subsys.type)); - goto error; + goto cleanup; } ret = 0; - error: + cleanup: VIR_FREE(managed); VIR_FREE(sgio); VIR_FREE(rawio); -- 2.14.4

On Wed, Jul 11, 2018 at 03:58:25PM +0200, Erik Skultety wrote:
The exit path is the same for both success and failure, so the label should be called cleanup.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/conf/domain_conf.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

QEMU 2.12 introduced a new type of display for mediated devices using vfio-pci backend which allows a mediated device to be used as a VGA compatible device as an alternative to an emulated video device. QEMU exposes this feature via a vfio device property 'display' with supported values 'on/off/auto' (default is 'off'). This patch adds the necessary bits to domain config handling in order to expose this feature. Since there's no convenient way for libvirt to come up with usable defaults for the display setting, simply because libvirt is not able to figure out which of the display implementations - dma-buf which requires OpenGL support vs vfio regions which doesn't need OpenGL (works with OpenGL enabled too) - the underlying mdev uses. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- docs/formatdomain.html.in | 20 ++++++-- docs/schemas/domaincommon.rng | 5 ++ src/conf/domain_conf.c | 19 +++++++- src/conf/domain_conf.h | 1 + src/qemu/qemu_domain.c | 55 ++++++++++++++++++++++ tests/qemuxml2argvdata/hostdev-mdev-display.xml | 39 +++++++++++++++ .../hostdev-mdev-display-active.xml | 47 ++++++++++++++++++ tests/qemuxml2xmltest.c | 2 + 8 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display.xml create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display-active.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 9dd22554ad..3554c3dc30 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -4510,9 +4510,23 @@ guest. Currently, <code>model='vfio-pci'</code> and <code>model='vfio-ccw'</code> (<span class="since">Since 4.4.0</span>) is supported. Refer <a href="drvnodedev.html#MDEV">MDEV</a> to create - a mediated device on the host. There are also some implications on the - usage of guest's address type depending on the <code>model</code> - attribute, see the <code>address</code> element below. + a mediated device on the host. + <span class="since">Since 4.6.0 (QEMU 2.12)</span> an optional + <code>display</code> attribute may be used to enable or disable + support for an accelerated remote desktop backed by a mediated + device (such as NVIDIA vGPU or Intel GVT-g) as an alternative to + emulated <a href="#elementsVideo">video devices</a>. This attribute + is limited to <code>model='vfio-pci'</code> only. Supported values + are either <code>on</code> or <code>off</code> (default is 'off'). + It is required to use a + <a href="#elementsGraphics">graphical framebuffer</a> in order to + use this attribute, currently only supported with VNC, Spice and + egl-headless graphics devices. + <p> + Note: There are also some implications on the usage of guest's + address type depending on the <code>model</code> attribute, + see the <code>address</code> element below. + </p> </dd> </dl> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 8f7d273d9f..b8ec9c758a 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4576,6 +4576,11 @@ <value>vfio-ccw</value> </choice> </attribute> + <optional> + <attribute name="display"> + <ref name="virOnOff"/> + </attribute> + </optional> <element name="source"> <ref name="mdevaddress"/> </element> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8deff5442f..bd1dc0780d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7646,6 +7646,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, char *rawio = NULL; char *backendStr = NULL; char *model = NULL; + char *display = NULL; int backend; int ret = -1; virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci; @@ -7665,6 +7666,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, sgio = virXMLPropString(node, "sgio"); rawio = virXMLPropString(node, "rawio"); model = virXMLPropString(node, "model"); + display = virXMLPropString(node, "display"); /* @type is passed in from the caller rather than read from the * xml document, because it is specified in different places for @@ -7752,6 +7754,15 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, model); goto cleanup; } + + if (display && + (mdevsrc->display = virTristateSwitchTypeFromString(display)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown value '%s' for <hostdev> attribute " + "'display'"), + display); + goto cleanup; + } } switch (def->source.subsys.type) { @@ -7805,6 +7816,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, VIR_FREE(rawio); VIR_FREE(backendStr); VIR_FREE(model); + VIR_FREE(display); return ret; } @@ -26558,9 +26570,14 @@ virDomainHostdevDefFormat(virBufferPtr buf, virTristateBoolTypeToString(scsisrc->rawio)); } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV) + if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV) { virBufferAsprintf(buf, " model='%s'", virMediatedDeviceModelTypeToString(mdevsrc->model)); + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(buf, " display='%s'", + virTristateSwitchTypeToString(mdevsrc->display)); + } + } virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3deda1d978..8ca9558ceb 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -382,6 +382,7 @@ typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediated typedef virDomainHostdevSubsysMediatedDev *virDomainHostdevSubsysMediatedDevPtr; struct _virDomainHostdevSubsysMediatedDev { int model; /* enum virMediatedDeviceModelType */ + int display; /* virTristateSwitch */ char uuidstr[VIR_UUID_STRING_BUFLEN]; /* mediated device's uuid string */ }; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 5da8c8bfcc..a03b1fb029 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4450,10 +4450,47 @@ qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net) } +static int +qemuDomainMdevDefValidate(const virDomainHostdevSubsysMediatedDev *mdevsrc, + const virDomainDef *def) +{ + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT && + mdevsrc->model != VIR_MDEV_MODEL_TYPE_VFIO_PCI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("<hostdev> attribute 'display' is only supported" + " with model='vfio-pci'")); + + return -1; + } + + if (mdevsrc->display == VIR_TRISTATE_SWITCH_ON) { + if (def->ngraphics == 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("graphics device is needed for attribute value " + "'display=on' in <hostdev>")); + return -1; + } + + /* We're not able to tell whether an mdev needs OpenGL or not at the + * moment, so print a warning that an extra <gl> element or + * <graphics type='egl-headless/>' might be necessary to be added, + * depending on whether we're running with SPICE or VNC respectively. + */ + if (!virDomainGraphicsDefHasOpenGL(def)) + VIR_WARN("<hostdev> attribute 'display' may need the OpenGL to " + "be enabled"); + } + + return 0; +} + + static int qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef *hostdev, const virDomainDef *def) { + const virDomainHostdevSubsysMediatedDev *mdevsrc; + /* forbid capabilities mode hostdev in this kind of hypervisor */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -4463,6 +4500,24 @@ qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef *hostdev, return -1; } + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + switch ((virDomainHostdevSubsysType) hostdev->source.subsys.type) { + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + mdevsrc = &hostdev->source.subsys.u.mdev; + return qemuDomainMdevDefValidate(mdevsrc, def); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: + default: + virReportEnumRangeError(virDomainHostdevSubsysType, + hostdev->source.subsys.type); + return -1; + } + } + return 0; } diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display.xml b/tests/qemuxml2argvdata/hostdev-mdev-display.xml new file mode 100644 index 0000000000..f5b3575c04 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display.xml @@ -0,0 +1,39 @@ +<domain type='qemu' id='1'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + </controller> + <graphics type='vnc'/> + <hostdev mode='subsystem' type='mdev' model='vfio-pci' display='on'> + <source> + <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/> + </source> + </hostdev> + <video> + <model type='qxl' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/hostdev-mdev-display-active.xml b/tests/qemuxml2xmloutdata/hostdev-mdev-display-active.xml new file mode 100644 index 0000000000..63a1a00278 --- /dev/null +++ b/tests/qemuxml2xmloutdata/hostdev-mdev-display-active.xml @@ -0,0 +1,47 @@ +<domain type='qemu' id='1'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='vnc' port='-1' autoport='yes'> + <listen type='address'/> + </graphics> + <video> + <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='on'> + <source> + <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/> + </source> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </hostdev> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 3527ccdec3..14324b9c02 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -477,6 +477,8 @@ mymain(void) DO_TEST("hostdev-pci-address", NONE); DO_TEST("hostdev-vfio", NONE); DO_TEST("hostdev-mdev-precreated", NONE); + DO_TEST_FULL("hostdev-mdev-display", WHEN_ACTIVE, GIC_NONE, + QEMU_CAPS_VFIO_PCI_DISPLAY); DO_TEST("pci-rom", NONE); DO_TEST("pci-rom-disabled", NONE); DO_TEST("pci-rom-disabled-invalid", NONE); -- 2.14.4

On Wed, Jul 11, 2018 at 03:58:26PM +0200, Erik Skultety wrote:
QEMU 2.12 introduced a new type of display for mediated devices using vfio-pci backend which allows a mediated device to be used as a VGA compatible device as an alternative to an emulated video device. QEMU exposes this feature via a vfio device property 'display' with supported values 'on/off/auto' (default is 'off').
This patch adds the necessary bits to domain config handling in order to expose this feature. Since there's no convenient way for libvirt to come up with usable defaults for the display setting, simply because libvirt is not able to figure out which of the display implementations - dma-buf which requires OpenGL support vs vfio regions which doesn't need OpenGL (works with OpenGL enabled too) - the underlying mdev uses.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- docs/formatdomain.html.in | 20 ++++++-- docs/schemas/domaincommon.rng | 5 ++ src/conf/domain_conf.c | 19 +++++++- src/conf/domain_conf.h | 1 + src/qemu/qemu_domain.c | 55 ++++++++++++++++++++++ tests/qemuxml2argvdata/hostdev-mdev-display.xml | 39 +++++++++++++++ .../hostdev-mdev-display-active.xml | 47 ++++++++++++++++++ tests/qemuxml2xmltest.c | 2 + 8 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display.xml create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display-active.xml
@@ -7752,6 +7754,15 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, model); goto cleanup; } + + if (display && + (mdevsrc->display = virTristateSwitchTypeFromString(display)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown value '%s' for <hostdev> attribute " + "'display'"), + display); + goto cleanup; + } }
switch (def->source.subsys.type) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3deda1d978..8ca9558ceb 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -382,6 +382,7 @@ typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediated typedef virDomainHostdevSubsysMediatedDev *virDomainHostdevSubsysMediatedDevPtr; struct _virDomainHostdevSubsysMediatedDev { int model; /* enum virMediatedDeviceModelType */ + int display; /* virTristateSwitch */
I was convinced that using the enum type here is the right way, but I've had my illusions shattered. If you decide to go that way anyway, don't forget to use a temporary int variable in the parser, since the compiler can choose to make virTristateSwitch unsinged and it won't be able to hold the negative return value from virTristateSwitchTypeFromString.
char uuidstr[VIR_UUID_STRING_BUFLEN]; /* mediated device's uuid string */ };
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 5da8c8bfcc..a03b1fb029 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4450,10 +4450,47 @@ qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net) }
+static int +qemuDomainMdevDefValidate(const virDomainHostdevSubsysMediatedDev *mdevsrc, + const virDomainDef *def) +{ + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT && + mdevsrc->model != VIR_MDEV_MODEL_TYPE_VFIO_PCI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("<hostdev> attribute 'display' is only supported" + " with model='vfio-pci'")); + + return -1; + } + + if (mdevsrc->display == VIR_TRISTATE_SWITCH_ON) { + if (def->ngraphics == 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("graphics device is needed for attribute value " + "'display=on' in <hostdev>")); + return -1; + } + + /* We're not able to tell whether an mdev needs OpenGL or not at the + * moment, so print a warning that an extra <gl> element or + * <graphics type='egl-headless/>' might be necessary to be added, + * depending on whether we're running with SPICE or VNC respectively. + */ + if (!virDomainGraphicsDefHasOpenGL(def)) + VIR_WARN("<hostdev> attribute 'display' may need the OpenGL to " + "be enabled");
I'd suggest dropping the warning - nobody reads warnings.
+ } + + return 0; +} + + static int
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Since QEMU 2.12, QEMU understands a new vfio-pci device option 'display' which can be used to turn on display capabilities on vgpu-enabled mediated devices, IOW emulated GPU devices like QXL will no longer be needed with vgpu-enable mdevs. QEMU defaults to 'auto' for the 'display' attribute, which is not foolproof, so we need to play it safe here and explicitly format display='off' if this attribute wasn't provided in the XML explicitly. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_command.c | 25 ++++++++++++- .../hostdev-mdev-display-missing-graphics.xml | 35 ++++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.args | 32 +++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 +++++++++++++++++++++ .../hostdev-mdev-display-spice-opengl.args | 31 ++++++++++++++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.args | 32 +++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 +++++++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.args | 31 ++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 31 ++++++++++++++++ 11 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 48e224cabc..5f6b340f8f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5207,6 +5207,26 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, virBufferAdd(&buf, dev_str, -1); virBufferAsprintf(&buf, ",id=%s,sysfsdev=%s", dev->info->alias, mdevPath); + /* QEMU 2.12 added support for vfio-pci display type, we need to perform + * some additional checks here */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_DISPLAY)) { + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("display property of device vfio-pci is " + "not supported by this version of QEMU")); + goto cleanup; + } + } else { + /* we default to 'display=off', since QEMU defaults to 'auto' which is + * unreliable and we don't want to risk any breakages */ + if (mdevsrc->display == VIR_TRISTATE_SWITCH_ABSENT) + mdevsrc->display = VIR_TRISTATE_SWITCH_OFF; + } + + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(&buf, ",display=%s", + virTristateSwitchTypeToString(mdevsrc->display)); + if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0) goto cleanup; @@ -5424,7 +5444,9 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, /* MDEV */ if (virHostdevIsMdevDevice(hostdev)) { - switch ((virMediatedDeviceModelType) subsys->u.mdev.model) { + virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev; + + switch ((virMediatedDeviceModelType) mdevsrc->model) { case VIR_MDEV_MODEL_TYPE_VFIO_PCI: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -5432,6 +5454,7 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, "supported by this version of QEMU")); return -1; } + break; case VIR_MDEV_MODEL_TYPE_VFIO_CCW: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_CCW)) { diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml b/tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml new file mode 100644 index 0000000000..ea559a6444 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml @@ -0,0 +1,35 @@ +<domain type='qemu'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + </controller> + <hostdev mode='subsystem' type='mdev' model='vfio-pci' display='on'> + <source> + <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/> + </source> + </hostdev> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.args b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.args new file mode 100644 index 0000000000..0d7792c938 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.args @@ -0,0 +1,32 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest2 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest2/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-spice port=0 \ +-display egl-headless \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0,\ +addr=0x2 \ +-device vfio-pci,id=hostdev0,\ +sysfsdev=/sys/bus/mdev/devices/53764d0e-85a0-42b4-af5c-2046b460b1dc,display=on,\ +bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml new file mode 100644 index 0000000000..c8f10c2f3a --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml @@ -0,0 +1,40 @@ +<domain type='qemu' id='1'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + </controller> + <graphics type='spice'/> + <graphics type='egl-headless'/> + <hostdev mode='subsystem' type='mdev' model='vfio-pci' display='on'> + <source> + <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/> + </source> + </hostdev> + <video> + <model type='qxl' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.args b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.args new file mode 100644 index 0000000000..170b4e4ed0 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.args @@ -0,0 +1,31 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest2 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest2/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-spice port=0,gl=on,rendernode=/dev/dri/foo \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0,\ +addr=0x2 \ +-device vfio-pci,id=hostdev0,\ +sysfsdev=/sys/bus/mdev/devices/53764d0e-85a0-42b4-af5c-2046b460b1dc,display=on,\ +bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml new file mode 100644 index 0000000000..18c9817608 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml @@ -0,0 +1,41 @@ +<domain type='qemu' id='1'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + </controller> + <graphics type='spice'> + <gl enable='yes' rendernode='/dev/dri/foo'/> + </graphics> + <hostdev mode='subsystem' type='mdev' model='vfio-pci' display='on'> + <source> + <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/> + </source> + </hostdev> + <video> + <model type='qxl' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.args b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.args new file mode 100644 index 0000000000..439e741b0d --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.args @@ -0,0 +1,32 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest2 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest2/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-vnc 127.0.0.1:0 \ +-display egl-headless \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0,\ +addr=0x2 \ +-device vfio-pci,id=hostdev0,\ +sysfsdev=/sys/bus/mdev/devices/53764d0e-85a0-42b4-af5c-2046b460b1dc,display=on,\ +bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml new file mode 100644 index 0000000000..b3eaeeef13 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml @@ -0,0 +1,40 @@ +<domain type='qemu' id='1'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + </controller> + <graphics type='vnc'/> + <graphics type='egl-headless'/> + <hostdev mode='subsystem' type='mdev' model='vfio-pci' display='on'> + <source> + <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/> + </source> + </hostdev> + <video> + <model type='qxl' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-vnc.args b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc.args new file mode 100644 index 0000000000..d1fa3e7b8c --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc.args @@ -0,0 +1,31 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest2 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest2/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-vnc 127.0.0.1:0 \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0,\ +addr=0x2 \ +-device vfio-pci,id=hostdev0,\ +sysfsdev=/sys/bus/mdev/devices/53764d0e-85a0-42b4-af5c-2046b460b1dc,display=on,\ +bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-vnc.xml b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc.xml new file mode 100644 index 0000000000..f5b3575c04 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc.xml @@ -0,0 +1,39 @@ +<domain type='qemu' id='1'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + </controller> + <graphics type='vnc'/> + <hostdev mode='subsystem' type='mdev' model='vfio-pci' display='on'> + <source> + <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/> + </source> + </hostdev> + <video> + <model type='qxl' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6014c81802..a0ab824038 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1590,6 +1590,37 @@ mymain(void) QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST_PARSE_ERROR("hostdev-mdev-invalid-target-address", QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST("hostdev-mdev-display-spice-opengl", + QEMU_CAPS_SPICE, + QEMU_CAPS_SPICE_GL, + QEMU_CAPS_SPICE_RENDERNODE, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-spice-egl-headless", + QEMU_CAPS_SPICE, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-vnc", + QEMU_CAPS_VNC, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-vnc-egl-headless", + QEMU_CAPS_VNC, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST_PARSE_ERROR("hostdev-mdev-display-missing-graphics", + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); DO_TEST("pci-rom", NONE); DO_TEST("pci-rom-disabled", NONE); DO_TEST("pci-rom-disabled-invalid", NONE); -- 2.14.4

On Wed, Jul 11, 2018 at 03:58:27PM +0200, Erik Skultety wrote:
Since QEMU 2.12, QEMU understands a new vfio-pci device option 'display' which can be used to turn on display capabilities on vgpu-enabled mediated devices, IOW emulated GPU devices like QXL will no longer be needed with vgpu-enable mdevs. QEMU defaults to 'auto' for the 'display' attribute, which is not foolproof, so we need to play it safe here and explicitly format display='off' if this attribute wasn't provided in the XML explicitly.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_command.c | 25 ++++++++++++- .../hostdev-mdev-display-missing-graphics.xml | 35 ++++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.args | 32 +++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 +++++++++++++++++++++ .../hostdev-mdev-display-spice-opengl.args | 31 ++++++++++++++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.args | 32 +++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 +++++++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.args | 31 ++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 31 ++++++++++++++++ 11 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 48e224cabc..5f6b340f8f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5207,6 +5207,26 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, virBufferAdd(&buf, dev_str, -1); virBufferAsprintf(&buf, ",id=%s,sysfsdev=%s", dev->info->alias, mdevPath);
+ /* QEMU 2.12 added support for vfio-pci display type, we need to perform + * some additional checks here */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_DISPLAY)) { + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("display property of device vfio-pci is " + "not supported by this version of QEMU")); + goto cleanup; + }
qemuCaps checks belong to *Validate functions.
+ } else { + /* we default to 'display=off', since QEMU defaults to 'auto' which is + * unreliable and we don't want to risk any breakages */ + if (mdevsrc->display == VIR_TRISTATE_SWITCH_ABSENT) + mdevsrc->display = VIR_TRISTATE_SWITCH_OFF; + } + + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(&buf, ",display=%s", + virTristateSwitchTypeToString(mdevsrc->display)); + if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0) goto cleanup;
@@ -5424,7 +5444,9 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
/* MDEV */ if (virHostdevIsMdevDevice(hostdev)) { - switch ((virMediatedDeviceModelType) subsys->u.mdev.model) { + virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev; + + switch ((virMediatedDeviceModelType) mdevsrc->model) { case VIR_MDEV_MODEL_TYPE_VFIO_PCI: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -5432,6 +5454,7 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, "supported by this version of QEMU")); return -1; } + break; case VIR_MDEV_MODEL_TYPE_VFIO_CCW: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_CCW)) {
These two hunks are unrelated. Feel free to push them as trivial in a separate commit.
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6014c81802..a0ab824038 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1590,6 +1590,37 @@ mymain(void) QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST_PARSE_ERROR("hostdev-mdev-invalid-target-address", QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST("hostdev-mdev-display-spice-opengl", + QEMU_CAPS_SPICE, + QEMU_CAPS_SPICE_GL, + QEMU_CAPS_SPICE_RENDERNODE, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-spice-egl-headless", + QEMU_CAPS_SPICE, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-vnc", + QEMU_CAPS_VNC, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-vnc-egl-headless", + QEMU_CAPS_VNC, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY);
Can you use DO_TEST_CAPS_LATEST for these tests?
+ DO_TEST_PARSE_ERROR("hostdev-mdev-display-missing-graphics", + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); DO_TEST("pci-rom", NONE); DO_TEST("pci-rom-disabled", NONE); DO_TEST("pci-rom-disabled-invalid", NONE);
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

On Fri, Jul 13, 2018 at 03:06:05PM +0200, Ján Tomko wrote:
On Wed, Jul 11, 2018 at 03:58:27PM +0200, Erik Skultety wrote:
Since QEMU 2.12, QEMU understands a new vfio-pci device option 'display' which can be used to turn on display capabilities on vgpu-enabled mediated devices, IOW emulated GPU devices like QXL will no longer be needed with vgpu-enable mdevs. QEMU defaults to 'auto' for the 'display' attribute, which is not foolproof, so we need to play it safe here and explicitly format display='off' if this attribute wasn't provided in the XML explicitly.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_command.c | 25 ++++++++++++- .../hostdev-mdev-display-missing-graphics.xml | 35 ++++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.args | 32 +++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 +++++++++++++++++++++ .../hostdev-mdev-display-spice-opengl.args | 31 ++++++++++++++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.args | 32 +++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 +++++++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.args | 31 ++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 31 ++++++++++++++++ 11 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 48e224cabc..5f6b340f8f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5207,6 +5207,26 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, virBufferAdd(&buf, dev_str, -1); virBufferAsprintf(&buf, ",id=%s,sysfsdev=%s", dev->info->alias, mdevPath);
+ /* QEMU 2.12 added support for vfio-pci display type, we need to perform + * some additional checks here */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_DISPLAY)) { + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("display property of device vfio-pci is " + "not supported by this version of QEMU")); + goto cleanup; + }
qemuCaps checks belong to *Validate functions.
Well, we still need to come up with the default value, but only in case QEMU has the cap and we already agreed upon not doing this in postparse, otherwise we'd format something into the offline config even if there was no input from the user, so I'd like to keep it this way, otherwise the capability check would have to be at 2 places instead of 1.
+ } else { + /* we default to 'display=off', since QEMU defaults to 'auto' which is + * unreliable and we don't want to risk any breakages */ + if (mdevsrc->display == VIR_TRISTATE_SWITCH_ABSENT) + mdevsrc->display = VIR_TRISTATE_SWITCH_OFF; + } + + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(&buf, ",display=%s", + virTristateSwitchTypeToString(mdevsrc->display)); + if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0) goto cleanup;
@@ -5424,7 +5444,9 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
/* MDEV */ if (virHostdevIsMdevDevice(hostdev)) { - switch ((virMediatedDeviceModelType) subsys->u.mdev.model) { + virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev; + + switch ((virMediatedDeviceModelType) mdevsrc->model) { case VIR_MDEV_MODEL_TYPE_VFIO_PCI: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -5432,6 +5454,7 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, "supported by this version of QEMU")); return -1; } + break; case VIR_MDEV_MODEL_TYPE_VFIO_CCW: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_CCW)) {
These two hunks are unrelated. Feel free to push them as trivial in a separate commit.
Will do.
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6014c81802..a0ab824038 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1590,6 +1590,37 @@ mymain(void) QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST_PARSE_ERROR("hostdev-mdev-invalid-target-address", QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST("hostdev-mdev-display-spice-opengl", + QEMU_CAPS_SPICE, + QEMU_CAPS_SPICE_GL, + QEMU_CAPS_SPICE_RENDERNODE, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-spice-egl-headless", + QEMU_CAPS_SPICE, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-vnc", + QEMU_CAPS_VNC, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("hostdev-mdev-display-vnc-egl-headless", + QEMU_CAPS_VNC, + QEMU_CAPS_EGL_HEADLESS, + QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY);
Can you use DO_TEST_CAPS_LATEST for these tests?
Oh, I didn't know we had that, sure, I can go with that except for the first test which needs _SPICE_GL, however, that is only filled after scanning the command line options, so there is no such capability in the data set. Erik
+ DO_TEST_PARSE_ERROR("hostdev-mdev-display-missing-graphics", + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); DO_TEST("pci-rom", NONE); DO_TEST("pci-rom-disabled", NONE); DO_TEST("pci-rom-disabled-invalid", NONE);
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Jano

On Mon, Jul 16, 2018 at 03:51:40PM +0200, Erik Skultety wrote:
On Fri, Jul 13, 2018 at 03:06:05PM +0200, Ján Tomko wrote:
On Wed, Jul 11, 2018 at 03:58:27PM +0200, Erik Skultety wrote:
Since QEMU 2.12, QEMU understands a new vfio-pci device option 'display' which can be used to turn on display capabilities on vgpu-enabled mediated devices, IOW emulated GPU devices like QXL will no longer be needed with vgpu-enable mdevs. QEMU defaults to 'auto' for the 'display' attribute, which is not foolproof, so we need to play it safe here and explicitly format display='off' if this attribute wasn't provided in the XML explicitly.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_command.c | 25 ++++++++++++- .../hostdev-mdev-display-missing-graphics.xml | 35 ++++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.args | 32 +++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 +++++++++++++++++++++ .../hostdev-mdev-display-spice-opengl.args | 31 ++++++++++++++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.args | 32 +++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 +++++++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.args | 31 ++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 31 ++++++++++++++++ 11 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 48e224cabc..5f6b340f8f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5207,6 +5207,26 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, virBufferAdd(&buf, dev_str, -1); virBufferAsprintf(&buf, ",id=%s,sysfsdev=%s", dev->info->alias, mdevPath);
+ /* QEMU 2.12 added support for vfio-pci display type, we need to perform + * some additional checks here */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_DISPLAY)) { + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("display property of device vfio-pci is " + "not supported by this version of QEMU")); + goto cleanup; + }
qemuCaps checks belong to *Validate functions.
Well, we still need to come up with the default value, but only in case QEMU has the cap and we already agreed upon not doing this in postparse,
By putting it in postParse you get the benefit of preserving this default for future starts (if we ever can and decide to change the default) and more importantly it gets displayed in the domain XML.
otherwise we'd format something into the offline config even if there was no input from the user, so I'd like to keep it this way, otherwise the capability check would have to be at 2 places instead of 1.
You can create a domain with pretty minimal XML and we will fill in all the sensible defaults, there's no reason to treat this attribute differently. Jano

Signed-off-by: Erik Skultety <eskultet@redhat.com> Acked-by: Michal Privoznik <mprivozn@redhat.com> --- docs/news.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 773c95b0da..fd08c01aeb 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -44,6 +44,16 @@ support should be available to the guest. </description> </change> + <change> + <summary> + qemu: Enable VNC console for mediated devices + </summary> + <description> + Host devices now support a new atribute 'display' which can be used + to turn on frame buffer rendering on a vgpu mediated device instead of + on an emulated GPU, like QXL. + </description> + </change> </section> <section title="Improvements"> </section> -- 2.14.4
participants (2)
-
Erik Skultety
-
Ján Tomko