[libvirt] [PATCH v4 00/10] 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 Since v3 [3]: - all of the patches got a RB, but there were some comments that made me send another version - the only major change was to move the default 'display' choice from qemu_command.c back to a PostParse callback, so now we format display='off' by default to every domain that utilized an mdev [1] https://www.redhat.com/archives/libvir-list/2018-June/msg01740.html [2] https://www.redhat.com/archives/libvir-list/2018-July/msg00485.html [3] https://www.redhat.com/archives/libvir-list/2018-July/msg00698.html Erik Skultety (9): qemu: qemuBuildHostdevCommandLine: Use a helper variable mdevsrc qemu: caps: Introduce a capability for egl-headless qemu: 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 Katerina Koukiou (1): docs: formatdomain: unify naming for CPUs/vCPUs docs/formatdomain.html.in | 137 ++++++++++++------ 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 | 23 ++- src/qemu/qemu_domain.c | 154 ++++++++++++++++++++- 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.11.0.x86_64.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 +++++ ...v-display-spice-egl-headless.x86_64-latest.args | 37 +++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 ++++++ ...ev-mdev-display-spice-opengl.x86_64-latest.args | 36 +++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++ ...dev-display-vnc-egl-headless.x86_64-latest.args | 37 +++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 ++++++ .../hostdev-mdev-display-vnc.x86_64-latest.args | 36 +++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++ tests/qemuxml2argvdata/hostdev-mdev-display.xml | 39 ++++++ tests/qemuxml2argvtest.c | 24 ++++ .../graphics-spice-egl-headless.xml | 44 ++++++ .../graphics-vnc-egl-headless.xml | 42 ++++++ tests/qemuxml2xmloutdata/hostdev-mdev-display.xml | 47 +++++++ tests/qemuxml2xmltest.c | 3 + 51 files changed, 1214 insertions(+), 73 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.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.x86_64-latest.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.xml -- 2.14.4

From: Katerina Koukiou <kkoukiou@redhat.com> CPU is an acronym and should be written in uppercase when part of plain text and not refering to an element. Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- docs/formatdomain.html.in | 84 +++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index b00971a945..d08ede9ab5 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -631,45 +631,45 @@ </dd> <dt><code>vcpus</code></dt> <dd> - The vcpus element allows to control state of individual vcpus. + The vcpus element allows to control state of individual vCPUs. The <code>id</code> attribute specifies the vCPU id as used by libvirt - in other places such as vcpu pinning, scheduler information and NUMA - assignment. Note that the vcpu ID as seen in the guest may differ from - libvirt ID in certain cases. Valid IDs are from 0 to the maximum vcpu + in other places such as vCPU pinning, scheduler information and NUMA + assignment. Note that the vCPU ID as seen in the guest may differ from + libvirt ID in certain cases. Valid IDs are from 0 to the maximum vCPU count as set by the <code>vcpu</code> element minus 1. The <code>enabled</code> attribute allows to control the state of the - vcpu. Valid values are <code>yes</code> and <code>no</code>. + vCPU. Valid values are <code>yes</code> and <code>no</code>. - <code>hotpluggable</code> controls whether given vcpu can be hotplugged - and hotunplugged in cases when the cpu is enabled at boot. Note that - all disabled vcpus must be hotpluggable. Valid values are + <code>hotpluggable</code> controls whether given vCPU can be hotplugged + and hotunplugged in cases when the CPU is enabled at boot. Note that + all disabled vCPUs must be hotpluggable. Valid values are <code>yes</code> and <code>no</code>. - <code>order</code> allows to specify the order to add the online vcpus. - For hypervisors/platforms that require to insert multiple vcpus at once - the order may be duplicated across all vcpus that need to be - enabled at once. Specifying order is not necessary, vcpus are then + <code>order</code> allows to specify the order to add the online vCPUs. + For hypervisors/platforms that require to insert multiple vCPUs at once + the order may be duplicated across all vCPUs that need to be + enabled at once. Specifying order is not necessary, vCPUs are then added in an arbitrary order. If order info is used, it must be used for - all online vcpus. Hypervisors may clear or update ordering information + all online vCPUs. Hypervisors may clear or update ordering information during certain operations to assure valid configuration. - Note that hypervisors may create hotpluggable vcpus differently from - boot vcpus thus special initialization may be necessary. + Note that hypervisors may create hotpluggable vCPUs differently from + boot vCPUs thus special initialization may be necessary. - Hypervisors may require that vcpus enabled on boot which are not + Hypervisors may require that vCPUs enabled on boot which are not hotpluggable are clustered at the beginning starting with ID 0. It may - be also required that vcpu 0 is always present and non-hotpluggable. + be also required that vCPU 0 is always present and non-hotpluggable. - Note that providing state for individual cpus may be necessary to enable + Note that providing state for individual CPUs may be necessary to enable support of addressable vCPU hotplug and this feature may not be supported by all hypervisors. - For QEMU the following conditions are required. Vcpu 0 needs to be - enabled and non-hotpluggable. On PPC64 along with it vcpus that are in - the same core need to be enabled as well. All non-hotpluggable cpus - present at boot need to be grouped after vcpu 0. + For QEMU the following conditions are required. vCPU 0 needs to be + enabled and non-hotpluggable. On PPC64 along with it vCPUs that are in + the same core need to be enabled as well. All non-hotpluggable CPUs + present at boot need to be grouped after vCPU 0. <span class="since">Since 2.2.0 (QEMU only)</span> </dd> </dl> @@ -774,11 +774,11 @@ <dt><code>vcpupin</code></dt> <dd> The optional <code>vcpupin</code> element specifies which of host's - physical CPUs the domain VCPU will be pinned to. If this is omitted, + physical CPUs the domain vCPU will be pinned to. If this is omitted, and attribute <code>cpuset</code> of element <code>vcpu</code> is not specified, the vCPU is pinned to all the physical CPUs by default. It contains two required attributes, the attribute <code>vcpu</code> - specifies vcpu id, and the attribute <code>cpuset</code> is same as + specifies vCPU id, and the attribute <code>cpuset</code> is same as attribute <code>cpuset</code> of element <code>vcpu</code>. (NB: Only qemu driver support) <span class="since">Since 0.9.0</span> @@ -786,7 +786,7 @@ <dt><code>emulatorpin</code></dt> <dd> The optional <code>emulatorpin</code> element specifies which of host - physical CPUs the "emulator", a subset of a domain not including vcpu + physical CPUs the "emulator", a subset of a domain not including vCPU or iothreads will be pinned to. If this is omitted, and attribute <code>cpuset</code> of element <code>vcpu</code> is not specified, "emulator" is pinned to all the physical CPUs by default. It contains @@ -820,7 +820,7 @@ <dt><code>period</code></dt> <dd> The optional <code>period</code> element specifies the enforcement - interval(unit: microseconds). Within <code>period</code>, each vcpu of + interval(unit: microseconds). Within <code>period</code>, each vCPU of the domain will not be allowed to consume more than <code>quota</code> worth of runtime. The value should be in range [1000, 1000000]. A period with value 0 means no value. @@ -835,7 +835,7 @@ vCPU threads, which means that it is not bandwidth controlled. The value should be in range [1000, 18446744073709551] or less than 0. A quota with value 0 means no value. You can use this feature to ensure that all - vcpus run at the same speed. + vCPUs run at the same speed. <span class="since">Only QEMU driver support since 0.9.4, LXC since 0.9.10</span> </dd> @@ -864,7 +864,7 @@ <dd> The optional <code>emulator_period</code> element specifies the enforcement interval(unit: microseconds). Within <code>emulator_period</code>, emulator - threads(those excluding vcpus) of the domain will not be allowed to consume + threads(those excluding vCPUs) of the domain will not be allowed to consume more than <code>emulator_quota</code> worth of runtime. The value should be in range [1000, 1000000]. A period with value 0 means no value. <span class="since">Only QEMU driver support since 0.10.0</span> @@ -873,9 +873,9 @@ <dd> The optional <code>emulator_quota</code> element specifies the maximum allowed bandwidth(unit: microseconds) for domain's emulator threads(those - excluding vcpus). A domain with <code>emulator_quota</code> as any negative + excluding vCPUs). A domain with <code>emulator_quota</code> as any negative value indicates that the domain has infinite bandwidth for emulator threads - (those excluding vcpus), which means that it is not bandwidth controlled. + (those excluding vCPUs), which means that it is not bandwidth controlled. The value should be in range [1000, 18446744073709551] or less than 0. A quota with value 0 means no value. <span class="since">Only QEMU driver support since 0.10.0</span> @@ -2131,13 +2131,13 @@ QEMU, the user-configurable extended TSEG feature was unavailable up to and including <code>pc-q35-2.9</code>. Starting with <code>pc-q35-2.10</code> the feature is available, with default size - 16 MiB. That should suffice for up to roughly 272 VCPUs, 5 GiB guest + 16 MiB. That should suffice for up to roughly 272 vCPUs, 5 GiB guest RAM in total, no hotplug memory range, and 32 GiB of 64-bit PCI MMIO - aperture. Or for 48 VCPUs, with 1TB of guest RAM, no hotplug DIMM + aperture. Or for 48 vCPUs, with 1TB of guest RAM, no hotplug DIMM range, and 32GB of 64-bit PCI MMIO aperture. The values may also vary based on the loader the VM is using. </p><p> - Additional size might be needed for significantly higher VCPU counts + Additional size might be needed for significantly higher vCPU counts or increased address space (that can be memory, maxMemory, 64-bit PCI MMIO aperture size; roughly 8 MiB of TSEG per 1 TiB of address space) which can also be rounded up. @@ -2147,7 +2147,7 @@ documentation of the guest OS or loader (if there is any), or test this by trial-and-error changing the value until the VM boots successfully. Yet another guiding value for users might be the fact - that 48 MiB should be enough for pretty large guests (240 VCPUs and + that 48 MiB should be enough for pretty large guests (240 vCPUs and 4TB guest RAM), but it is on purpose not set as default as 48 MiB of unavailable RAM might be too much for small guests (e.g. with 512 MiB of RAM). @@ -2425,7 +2425,7 @@ </tr> <tr> <td><code>cpu_cycles</code></td> - <td>the count of cpu cycles (total/elapsed)</td> + <td>the count of CPU cycles (total/elapsed)</td> <td><code>perf.cpu_cycles</code></td> </tr> <tr> @@ -2460,25 +2460,25 @@ </tr> <tr> <td><code>stalled_cycles_frontend</code></td> - <td>the count of stalled cpu cycles in the frontend of the instruction + <td>the count of stalled CPU cycles in the frontend of the instruction processor pipeline by applications running on the platform</td> <td><code>perf.stalled_cycles_frontend</code></td> </tr> <tr> <td><code>stalled_cycles_backend</code></td> - <td>the count of stalled cpu cycles in the backend of the instruction + <td>the count of stalled CPU cycles in the backend of the instruction processor pipeline by applications running on the platform</td> <td><code>perf.stalled_cycles_backend</code></td> </tr> <tr> <td><code>ref_cpu_cycles</code></td> - <td>the count of total cpu cycles not affected by CPU frequency scaling + <td>the count of total CPU cycles not affected by CPU frequency scaling by applications running on the platform</td> <td><code>perf.ref_cpu_cycles</code></td> </tr> <tr> <td><code>cpu_clock</code></td> - <td>the count of cpu clock time, as measured by a monotonic + <td>the count of CPU clock time, as measured by a monotonic high-resolution per-CPU timer, by applications running on the platform</td> <td><code>perf.cpu_clock</code></td> @@ -2505,7 +2505,7 @@ </tr> <tr> <td><code>cpu_migrations</code></td> - <td>the count of cpu migrations, that is, where the process + <td>the count of CPU migrations, that is, where the process moved from one logical processor to another, by applications running on the platform</td> <td><code>perf.cpu_migrations</code></td> @@ -5621,8 +5621,8 @@ qemu-kvm -net nic,model=? /dev/null The resulting difference, according to the qemu developer who added the option is: "bh makes tx more asynchronous and reduces latency, but potentially causes more processor bandwidth - contention since the cpu doing the tx isn't necessarily the - cpu where the guest generated the packets."<br/><br/> + contention since the CPU doing the tx isn't necessarily the + CPU where the guest generated the packets."<br/><br/> <b>In general you should leave this option alone, unless you are very certain you know what you are doing.</b> -- 2.14.4

Decrease the number of accessors we have to use. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_command.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 44ae8dcef7..c628ac3985 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5424,7 +5424,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 +5434,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)) { -- 2.14.4

On Wed, Jul 18, 2018 at 02:31:38PM +0200, Erik Skultety wrote:
Decrease the number of accessors we have to use.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_command.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

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> Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Erik Skultety <eskultet@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.11.0.x86_64.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 + 14 files changed, 19 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.11.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml index c52e44a498..210f774c4e 100644 --- a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml @@ -207,6 +207,7 @@ <flag name='tpm-emulator'/> <flag name='mch'/> <flag name='mch.extended-tseg-mbytes'/> + <flag name='egl-headless'/> <version>2011000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>371455</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 cd036d9323..431910a9e3 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml @@ -214,6 +214,7 @@ <flag name='mch.extended-tseg-mbytes'/> <flag name='sev-guest'/> <flag name='usb-storage.werror'/> + <flag name='egl-headless'/> <version>2012090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>438109</microcodeVersion> -- 2.14.4

On Wed, Jul 18, 2018 at 02:31:39PM +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> Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Erik Skultety <eskultet@redhat.com>
Sigh, consider this extra SoB removed, that's probably just some interactive rebase bit I forgot about. Erik

On Wed, Jul 18, 2018 at 02:57:30PM +0200, Erik Skultety wrote:
On Wed, Jul 18, 2018 at 02:31:39PM +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> Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Erik Skultety <eskultet@redhat.com>
Sigh, consider this extra SoB removed, that's probably just some interactive rebase bit I forgot about.
This happens if you use "-s" parameter, however, if you put your SoB always on the last line of the commit message "-s" will not add second one. Pavel
Erik
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On Wed, Jul 18, 2018 at 03:08:39PM +0200, Pavel Hrdina wrote:
On Wed, Jul 18, 2018 at 02:57:30PM +0200, Erik Skultety wrote:
On Wed, Jul 18, 2018 at 02:31:39PM +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> Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Erik Skultety <eskultet@redhat.com>
Sigh, consider this extra SoB removed, that's probably just some interactive rebase bit I forgot about.
This happens if you use "-s" parameter, however, if you put your SoB always on the last line of the commit message "-s" will not add second one.
Yeah, I should start adding the RBs above the SoB to prevent that, I'm not going to drop my auto-sign in the config, because I would just keep forgetting to sign it. Erik

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 | 14 ++++- src/qemu/qemu_domain.c | 60 +++++++++++++++++++++- 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, 488 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 d08ede9ab5..091888c879 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6321,7 +6321,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> @@ -6380,6 +6381,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> @@ -6485,6 +6491,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. @@ -6520,6 +6532,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 f24a56392a..157726752c 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 c628ac3985..7c44045d61 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8216,6 +8216,7 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, return -1; } + static int qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, virCommandPtr cmd, @@ -8245,6 +8246,11 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, qemuCaps, graphics) < 0) return -1; + break; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: + virCommandAddArg(cmd, "-display"); + virCommandAddArg(cmd, "egl-headless"); + break; case VIR_DOMAIN_GRAPHICS_TYPE_RDP: case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: @@ -10072,6 +10078,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 @@ -10113,6 +10120,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: @@ -10120,10 +10130,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..ce252b47eb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5528,6 +5528,60 @@ qemuDomainDeviceDefValidateTPM(virDomainTPMDef *tpm, } +static int +qemuDomainDeviceDefValidateGraphics(const virDomainGraphicsDef *graphics, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + bool have_egl_headless = false; + size_t i; + + 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 (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_EGL_HEADLESS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("egl-headless display is not supported with this " + "QEMU binary")); + return -1; + } + + 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 +5649,15 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, ret = qemuDomainDeviceDefValidateTPM(dev->data.tpm, def); break; + case VIR_DOMAIN_DEVICE_GRAPHICS: + ret = qemuDomainDeviceDefValidateGraphics(dev->data.graphics, def, + qemuCaps); + 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 847dab2edc..cc25c8ef54 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 2b6633a998..978dd8af72 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3702,6 +3702,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

On Wed, Jul 18, 2018 at 02:31:40PM +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 | 14 ++++- src/qemu/qemu_domain.c | 60 +++++++++++++++++++++- 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, 488 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
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> Reviewed-by: Ján Tomko <jtomko@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 431910a9e3..4bc7cfeebc 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml @@ -215,6 +215,7 @@ <flag name='sev-guest'/> <flag name='usb-storage.werror'/> <flag name='egl-headless'/> + <flag name='vfio-pci.display'/> <version>2012090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>438109</microcodeVersion> -- 2.14.4

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> Reviewed-by: Ján Tomko <jtomko@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 1caecb96b6..10496ff7dc 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

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> Reviewed-by: Ján Tomko <jtomko@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

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' (libvirt will default to '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> Reviewed-by: Ján Tomko <jtomko@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 | 94 ++++++++++++++++++++++- tests/qemuxml2argvdata/hostdev-mdev-display.xml | 39 ++++++++++ tests/qemuxml2xmloutdata/hostdev-mdev-display.xml | 47 ++++++++++++ tests/qemuxml2xmltest.c | 1 + 8 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display.xml create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 091888c879..3783e786ad 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -4532,9 +4532,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 157726752c..be8430ab22 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4579,6 +4579,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 ce252b47eb..97af2815cb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4450,10 +4450,49 @@ qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net) } +static int +qemuDomainMdevDefValidate(const virDomainHostdevSubsysMediatedDev *mdevsrc, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + if (mdevsrc->display == VIR_TRISTATE_SWITCH_ABSENT) + return 0; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_DISPLAY)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("display property of device vfio-pci is " + "not supported by this version of QEMU")); + return -1; + } + + if (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; + } + } + + return 0; +} + + static int qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef *hostdev, - const virDomainDef *def) + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) { + 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 +4502,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, qemuCaps); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: + default: + virReportEnumRangeError(virDomainHostdevSubsysType, + hostdev->source.subsys.type); + return -1; + } + } + return 0; } @@ -5621,7 +5678,8 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, break; case VIR_DOMAIN_DEVICE_HOSTDEV: - ret = qemuDomainDeviceDefValidateHostdev(dev->data.hostdev, def); + ret = qemuDomainDeviceDefValidateHostdev(dev->data.hostdev, def, + qemuCaps); break; case VIR_DOMAIN_DEVICE_VIDEO: @@ -6231,6 +6289,35 @@ qemuDomainVsockDefPostParse(virDomainVsockDefPtr vsock) } +static int +qemuDomainHostdevDefMdevPostParse(virDomainHostdevSubsysMediatedDevPtr mdevsrc, + virQEMUCapsPtr qemuCaps) +{ + /* QEMU 2.12 added support for vfio-pci display type, we default to + * 'display=off' to stay safe from future changes */ + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_DISPLAY) && + mdevsrc->display == VIR_TRISTATE_SWITCH_ABSENT) + mdevsrc->display = VIR_TRISTATE_SWITCH_OFF; + + return 0; +} + + +static int +qemuDomainHostdevDefPostParse(virDomainHostdevDefPtr hostdev, + virQEMUCapsPtr qemuCaps) +{ + virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; + + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV && + qemuDomainHostdevDefMdevPostParse(&subsys->u.mdev, qemuCaps) < 0) + return -1; + + return 0; +} + + static int qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, const virDomainDef *def, @@ -6286,6 +6373,9 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_HOSTDEV: + ret = qemuDomainHostdevDefPostParse(dev->data.hostdev, qemuCaps); + break; + case VIR_DOMAIN_DEVICE_WATCHDOG: case VIR_DOMAIN_DEVICE_GRAPHICS: case VIR_DOMAIN_DEVICE_HUB: diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display.xml b/tests/qemuxml2argvdata/hostdev-mdev-display.xml new file mode 100644 index 0000000000..f37e08e1b9 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display.xml @@ -0,0 +1,39 @@ +<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> + <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.xml b/tests/qemuxml2xmloutdata/hostdev-mdev-display.xml new file mode 100644 index 0000000000..94c11b1199 --- /dev/null +++ b/tests/qemuxml2xmloutdata/hostdev-mdev-display.xml @@ -0,0 +1,47 @@ +<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'> + <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..41e5ee9096 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -477,6 +477,7 @@ mymain(void) DO_TEST("hostdev-pci-address", NONE); DO_TEST("hostdev-vfio", NONE); DO_TEST("hostdev-mdev-precreated", NONE); + DO_TEST("hostdev-mdev-display", 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 18, 2018 at 02:31:44PM +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' (libvirt will default to '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> Reviewed-by: Ján Tomko <jtomko@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 | 94 ++++++++++++++++++++++- tests/qemuxml2argvdata/hostdev-mdev-display.xml | 39 ++++++++++ tests/qemuxml2xmloutdata/hostdev-mdev-display.xml | 47 ++++++++++++ tests/qemuxml2xmltest.c | 1 + 8 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display.xml create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display.xml
@@ -6286,6 +6373,9 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_HOSTDEV: + ret = qemuDomainHostdevDefPostParse(dev->data.hostdev, qemuCaps); + break;
This should only be called for VIR_DOMAIN_DEVICE_HOSTDEV, not the other device types listed above. Jano
+ case VIR_DOMAIN_DEVICE_WATCHDOG: case VIR_DOMAIN_DEVICE_GRAPHICS: case VIR_DOMAIN_DEVICE_HUB:

On Wed, Jul 18, 2018 at 05:06:28PM +0200, Ján Tomko wrote:
On Wed, Jul 18, 2018 at 02:31:44PM +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' (libvirt will default to '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> Reviewed-by: Ján Tomko <jtomko@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 | 94 ++++++++++++++++++++++- tests/qemuxml2argvdata/hostdev-mdev-display.xml | 39 ++++++++++ tests/qemuxml2xmloutdata/hostdev-mdev-display.xml | 47 ++++++++++++ tests/qemuxml2xmltest.c | 1 + 8 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display.xml create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display.xml
@@ -6286,6 +6373,9 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_HOSTDEV: + ret = qemuDomainHostdevDefPostParse(dev->data.hostdev, qemuCaps); + break;
This should only be called for VIR_DOMAIN_DEVICE_HOSTDEV, not the other device types listed above.
Doh! Thank you for pointing that out :), that would have ended interestingly. Erik

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 | 4 +++ .../hostdev-mdev-display-missing-graphics.xml | 35 ++++++++++++++++++ ...v-display-spice-egl-headless.x86_64-latest.args | 37 +++++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 +++++++++++++++++++++ ...ev-mdev-display-spice-opengl.x86_64-latest.args | 36 +++++++++++++++++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++++++++++++++++++ ...dev-display-vnc-egl-headless.x86_64-latest.args | 37 +++++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 +++++++++++++++++++++ .../hostdev-mdev-display-vnc.x86_64-latest.args | 36 +++++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 7 ++++ 11 files changed, 352 insertions(+) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.x86_64-latest.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 7c44045d61..c61da13893 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5207,6 +5207,10 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, virBufferAdd(&buf, dev_str, -1); virBufferAsprintf(&buf, ",id=%s,sysfsdev=%s", dev->info->alias, mdevPath); + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(&buf, ",display=%s", + virTristateSwitchTypeToString(mdevsrc->display)); + if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0) goto cleanup; 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.x86_64-latest.args b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.x86_64-latest.args new file mode 100644 index 0000000000..0ac90c81d2 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/usr/bin/qemu-system-i686 \ +-name guest=QEMUGuest2,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest2/master-key.aes \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-spice port=0,seamless-migration=on \ +-display egl-headless \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,\ +vram64_size_mb=0,vgamem_mb=16,max_outputs=1,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 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on 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.x86_64-latest.args b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.x86_64-latest.args new file mode 100644 index 0000000000..1fd9fdaa16 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.x86_64-latest.args @@ -0,0 +1,36 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/usr/bin/qemu-system-i686 \ +-name guest=QEMUGuest2,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest2/master-key.aes \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-spice port=0,gl=on,rendernode=/dev/dri/foo,seamless-migration=on \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,\ +vram64_size_mb=0,vgamem_mb=16,max_outputs=1,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 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on 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.x86_64-latest.args b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.x86_64-latest.args new file mode 100644 index 0000000000..cdf545d0e0 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name guest=QEMUGuest2,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest2/master-key.aes \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-vnc 127.0.0.1:0 \ +-display egl-headless \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,\ +vram64_size_mb=0,vgamem_mb=16,max_outputs=1,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 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on 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.x86_64-latest.args b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc.x86_64-latest.args new file mode 100644 index 0000000000..19439afda9 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-vnc.x86_64-latest.args @@ -0,0 +1,36 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name guest=QEMUGuest2,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest2/master-key.aes \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-vnc 127.0.0.1:0 \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,\ +vram64_size_mb=0,vgamem_mb=16,max_outputs=1,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 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on 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..bbde44327e 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1590,6 +1590,13 @@ mymain(void) QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST_PARSE_ERROR("hostdev-mdev-invalid-target-address", QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST_CAPS_LATEST("hostdev-mdev-display-spice-opengl"); + DO_TEST_CAPS_LATEST("hostdev-mdev-display-spice-egl-headless"); + DO_TEST_CAPS_LATEST("hostdev-mdev-display-vnc"); + DO_TEST_CAPS_LATEST("hostdev-mdev-display-vnc-egl-headless"); + 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 18, 2018 at 02:31:45PM +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.
Outdated comment, now that we set it in postParse.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_command.c | 4 +++ .../hostdev-mdev-display-missing-graphics.xml | 35 ++++++++++++++++++ ...v-display-spice-egl-headless.x86_64-latest.args | 37 +++++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 +++++++++++++++++++++ ...ev-mdev-display-spice-opengl.x86_64-latest.args | 36 +++++++++++++++++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++++++++++++++++++ ...dev-display-vnc-egl-headless.x86_64-latest.args | 37 +++++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 +++++++++++++++++++++ .../hostdev-mdev-display-vnc.x86_64-latest.args | 36 +++++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 7 ++++ 11 files changed, 352 insertions(+) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.x86_64-latest.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 7c44045d61..c61da13893 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5207,6 +5207,10 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, virBufferAdd(&buf, dev_str, -1); virBufferAsprintf(&buf, ",id=%s,sysfsdev=%s", dev->info->alias, mdevPath);
+ if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT)
To play it completely safe, we could add && qemuCapsGet(QEMU_CAPS_VFIO_PCI_DISPLAY) here, and allow having it set to VIR_TRISTATE_SWITCH_OFF in qemuDomainMdevDefValidate. But I'm not sure whether it's worth the trouble. Regardless Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
+ virTristateSwitchTypeToString(mdevsrc->display)); + if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0) goto cleanup;

On Wed, Jul 18, 2018 at 05:15:28PM +0200, Ján Tomko wrote:
On Wed, Jul 18, 2018 at 02:31:45PM +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.
Outdated comment, now that we set it in postParse.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_command.c | 4 +++ .../hostdev-mdev-display-missing-graphics.xml | 35 ++++++++++++++++++ ...v-display-spice-egl-headless.x86_64-latest.args | 37 +++++++++++++++++++ .../hostdev-mdev-display-spice-egl-headless.xml | 40 +++++++++++++++++++++ ...ev-mdev-display-spice-opengl.x86_64-latest.args | 36 +++++++++++++++++++ .../hostdev-mdev-display-spice-opengl.xml | 41 ++++++++++++++++++++++ ...dev-display-vnc-egl-headless.x86_64-latest.args | 37 +++++++++++++++++++ .../hostdev-mdev-display-vnc-egl-headless.xml | 40 +++++++++++++++++++++ .../hostdev-mdev-display-vnc.x86_64-latest.args | 36 +++++++++++++++++++ .../qemuxml2argvdata/hostdev-mdev-display-vnc.xml | 39 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 7 ++++ 11 files changed, 352 insertions(+) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-missing-graphics.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-spice-opengl.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc-egl-headless.xml create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-vnc.x86_64-latest.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 7c44045d61..c61da13893 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5207,6 +5207,10 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, virBufferAdd(&buf, dev_str, -1); virBufferAsprintf(&buf, ",id=%s,sysfsdev=%s", dev->info->alias, mdevPath);
+ if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT)
To play it completely safe, we could add && qemuCapsGet(QEMU_CAPS_VFIO_PCI_DISPLAY) here, and allow having it set to VIR_TRISTATE_SWITCH_OFF in qemuDomainMdevDefValidate.
So, we (or the user for that matter) put display='off' to the XML as result of the QEMU capability. If the user downgrades the version of QEMU to a version which doesn't provide the capability and feeds in the same XML, how is that a libvirt issue that we fail to start it? Yes, we can't crash or loose the definition, but IMHO that is the expected behaviour, you want something the emulator doesn't know...
But I'm not sure whether it's worth the trouble.
Regardless Reviewed-by: Ján Tomko <jtomko@redhat.com>
Thanks, I adjusted the commit message and will proceed with pushing the series. Erik

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 (3)
-
Erik Skultety
-
Ján Tomko
-
Pavel Hrdina