[libvirt] [PATCH 1/4] qemu: validate bochs-display capability

When the bochs display type was added, the capability was never checked. Add that check in the same place as the other video device capability checks. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/qemu/qemu_process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 955ba4de4c..b93af966e2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5278,7 +5278,9 @@ qemuProcessStartValidateVideo(virDomainObjPtr vm, !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU)) || (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO && video->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW))) { + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW)) || + (video->type == VIR_DOMAIN_VIDEO_TYPE_BOCHS && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_BOCHS_DISPLAY))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("this QEMU does not support '%s' video device"), virDomainVideoTypeToString(video->type)); -- 2.21.0

Add a qemu capbility to see if the standalone ramfb device is available. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 1 + 11 files changed, 12 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 9b19930964..99aa28c098 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -539,6 +539,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "migration-file-drop-cache", "net-socket-dgram", "dbus-vmstate", + "ramfb", ); @@ -1130,6 +1131,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "max-x86_64-cpu", QEMU_CAPS_X86_MAX_CPU }, { "bochs-display", QEMU_CAPS_DEVICE_BOCHS_DISPLAY }, { "dbus-vmstate", QEMU_CAPS_DBUS_VMSTATE }, + { "ramfb", QEMU_CAPS_DEVICE_RAMFB }, }; static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 54f91151c6..b2060b18a3 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -520,6 +520,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_MIGRATION_FILE_DROP_CACHE, /* migration with disk cache on is safe for type='file' disks */ QEMU_CAPS_NET_SOCKET_DGRAM, /* -net socket,fd= with dgram socket */ QEMU_CAPS_DBUS_VMSTATE, /* -object dbus-vmstate */ + QEMU_CAPS_DEVICE_RAMFB, /* -device ramfb */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml index 61be1df782..e8c249c62f 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml @@ -152,6 +152,7 @@ <flag name='iothread.poll-max-ns'/> <flag name='memory-backend-file.align'/> <flag name='bochs-display'/> + <flag name='ramfb'/> <version>2012050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900757</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml index 865becc179..05c0612ae9 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml @@ -92,6 +92,7 @@ <flag name='memory-backend-memfd.hugetlb'/> <flag name='iothread.poll-max-ns'/> <flag name='memory-backend-file.align'/> + <flag name='ramfb'/> <version>3000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml index eb54aeaff3..274bd0ee1d 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml @@ -92,6 +92,7 @@ <flag name='memory-backend-memfd.hugetlb'/> <flag name='iothread.poll-max-ns'/> <flag name='memory-backend-file.align'/> + <flag name='ramfb'/> <version>3000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml b/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml index d511377262..c44e7ca89f 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml @@ -123,6 +123,7 @@ <flag name='memory-backend-memfd.hugetlb'/> <flag name='iothread.poll-max-ns'/> <flag name='memory-backend-file.align'/> + <flag name='ramfb'/> <version>3000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100757</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml index 7a322030bd..8dcab37d7c 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml @@ -199,6 +199,7 @@ <flag name='nvdimm.unarmed'/> <flag name='x86-max-cpu'/> <flag name='bochs-display'/> + <flag name='ramfb'/> <version>3000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100757</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml index 434c644ad4..b5561aed2c 100644 --- a/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml @@ -202,6 +202,7 @@ <flag name='overcommit'/> <flag name='x86-max-cpu'/> <flag name='bochs-display'/> + <flag name='ramfb'/> <version>3000092</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100758</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml index 1627b2cb5e..c01bdc605b 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml @@ -166,6 +166,7 @@ <flag name='bochs-display'/> <flag name='migration-file-drop-cache'/> <flag name='net-socket-dgram'/> + <flag name='ramfb'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700758</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml index 79593c467a..a4ad6c5053 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml @@ -208,6 +208,7 @@ <flag name='bochs-display'/> <flag name='migration-file-drop-cache'/> <flag name='net-socket-dgram'/> + <flag name='ramfb'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100758</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml index 05e6538e37..1a55630a0c 100644 --- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml @@ -210,6 +210,7 @@ <flag name='bochs-display'/> <flag name='migration-file-drop-cache'/> <flag name='net-socket-dgram'/> + <flag name='ramfb'/> <version>4000050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100759</microcodeVersion> -- 2.21.0

This device is a very simple framebuffer device supported by qemu that is mostly intended to use as a boot framebuffer in conjunction with a vgpu. However, there is also a standalone ramfb device that can be used as a primary display device and is useful for e.g. aarch64 guests where different memory mappings between the host and guest can prevent use of other devices with framebuffers such as virtio-vga. https://bugzilla.redhat.com/show_bug.cgi?id=1679680 describes the issues in more detail. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- docs/formatdomain.html.in | 7 ++-- docs/news.xml | 9 +++++ docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 2 + src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 3 ++ src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain_address.c | 12 ++++-- src/qemu/qemu_process.c | 4 +- ...eo-ramfb-display-device.x86_64-latest.args | 38 +++++++++++++++++++ .../video-ramfb-display-device.xml | 29 ++++++++++++++ tests/qemuxml2argvtest.c | 1 + 12 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 tests/qemuxml2argvdata/video-ramfb-display-device.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/video-ramfb-display-device.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 86a5261e47..a8afe36756 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -7031,9 +7031,10 @@ qemu-kvm -net nic,model=? /dev/null "vbox", "qxl" (<span class="since">since 0.8.6</span>), "virtio" (<span class="since">since 1.3.0</span>), "gop" (<span class="since">since 3.2.0</span>), - "none" (<span class="since">since 4.6.0</span>, or "bochs" - (<span class="since">since 5.6.0</span>) - depending on the hypervisor features available. + "bochs" (<span class="since">since 5.6.0</span>), "ramfb" + (<span class="since">since 5.8.0</span>), or "none" + (<span class="since">since 4.6.0</span>, depending on the hypervisor + features available. The purpose of the type <code>none</code> is to instruct libvirt not to add a default video device in the guest (see the paragraph above). This legacy behaviour can be inconvenient in cases where GPU mediated diff --git a/docs/news.xml b/docs/news.xml index f6aee74884..b5e07f3844 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -41,6 +41,15 @@ <libvirt> <release version="v5.8.0" date="unreleased"> <section title="New features"> + <change> + <summary> + qemu: Introduce a new video model of type 'ramfb' + </summary> + <description> + Introduce a new video model type to the domain XML that supports the + <code>ramfb</code> standalone device in qemu. + </description> + </change> </section> <section title="Removed features"> <change> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index cae3be639e..e2cebb5739 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3590,6 +3590,7 @@ <value>gop</value> <value>none</value> <value>bochs</value> + <value>ramfb</value> </choice> </attribute> <group> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 96e9223e21..73840c327c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -742,6 +742,7 @@ VIR_ENUM_IMPL(virDomainVideo, "gop", "none", "bochs", + "ramfb", ); VIR_ENUM_IMPL(virDomainVideoVGAConf, @@ -15259,6 +15260,7 @@ virDomainVideoDefaultRAM(const virDomainDef *def, case VIR_DOMAIN_VIDEO_TYPE_VIRTIO: case VIR_DOMAIN_VIDEO_TYPE_GOP: case VIR_DOMAIN_VIDEO_TYPE_NONE: + case VIR_DOMAIN_VIDEO_TYPE_RAMFB: case VIR_DOMAIN_VIDEO_TYPE_LAST: default: return 0; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 82631ecb07..89e5fc1de8 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1389,6 +1389,7 @@ typedef enum { VIR_DOMAIN_VIDEO_TYPE_GOP, VIR_DOMAIN_VIDEO_TYPE_NONE, VIR_DOMAIN_VIDEO_TYPE_BOCHS, + VIR_DOMAIN_VIDEO_TYPE_RAMFB, VIR_DOMAIN_VIDEO_TYPE_LAST } virDomainVideoType; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f795f2e987..57ab70d35f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -114,6 +114,7 @@ VIR_ENUM_IMPL(qemuVideo, "" /* don't support gop */, "" /* 'none' doesn't make sense here */, "bochs-display", + "", /* ramfb can't be used with -vga */ ); VIR_ENUM_DECL(qemuDeviceVideo); @@ -132,6 +133,7 @@ VIR_ENUM_IMPL(qemuDeviceVideo, "" /* don't support gop */, "" /* 'none' doesn't make sense here */, "bochs-display", + "ramfb", ); VIR_ENUM_DECL(qemuDeviceVideoSecondary); @@ -150,6 +152,7 @@ VIR_ENUM_IMPL(qemuDeviceVideoSecondary, "" /* don't support gop */, "" /* 'none' doesn't make sense here */, "" /* no secondary device for bochs */, + "" /* no secondary device for ramfb */, ); VIR_ENUM_DECL(qemuSoundCodec); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index bd247628cb..8227d79d39 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5570,6 +5570,7 @@ qemuDomainDeviceDefValidateVideo(const virDomainVideoDef *video) case VIR_DOMAIN_VIDEO_TYPE_QXL: case VIR_DOMAIN_VIDEO_TYPE_VIRTIO: case VIR_DOMAIN_VIDEO_TYPE_BOCHS: + case VIR_DOMAIN_VIDEO_TYPE_RAMFB: case VIR_DOMAIN_VIDEO_TYPE_LAST: break; } diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 216ba6235e..91e5eb3603 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -936,6 +936,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev, case VIR_DOMAIN_VIDEO_TYPE_DEFAULT: case VIR_DOMAIN_VIDEO_TYPE_GOP: case VIR_DOMAIN_VIDEO_TYPE_NONE: + case VIR_DOMAIN_VIDEO_TYPE_RAMFB: case VIR_DOMAIN_VIDEO_TYPE_LAST: return 0; } @@ -1793,8 +1794,10 @@ qemuDomainValidateDevicePCISlotsPIIX3(virDomainDefPtr def, goto cleanup; } + /* ramfb is not a PCI device */ if (def->nvideos > 0 && - def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE) { + def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE && + def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_RAMFB) { /* Because the PIIX3 integrated IDE/USB controllers are * already at slot 1, when qemu looks for the first free slot * to place the VGA controller (which is always the first @@ -1983,8 +1986,10 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, goto cleanup; } + /* ramfb is not a PCI device */ if (def->nvideos > 0 && - def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE) { + def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE && + def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_RAMFB) { /* NB: unlike the pc machinetypes, on q35 machinetypes the * integrated devices are at slot 0x1f, so when qemu looks for * the first free slot for the first VGA, it will always be at @@ -2366,7 +2371,8 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, /* Video devices */ for (i = 0; i < def->nvideos; i++) { - if (def->videos[i]->type == VIR_DOMAIN_VIDEO_TYPE_NONE) + if (def->videos[i]->type == VIR_DOMAIN_VIDEO_TYPE_NONE || + def->videos[i]->type == VIR_DOMAIN_VIDEO_TYPE_RAMFB) continue; if (!virDeviceInfoPCIAddressIsWanted(&def->videos[i]->info)) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b93af966e2..013be5de13 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5280,7 +5280,9 @@ qemuProcessStartValidateVideo(virDomainObjPtr vm, video->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW)) || (video->type == VIR_DOMAIN_VIDEO_TYPE_BOCHS && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_BOCHS_DISPLAY))) { + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_BOCHS_DISPLAY)) || + (video->type == VIR_DOMAIN_VIDEO_TYPE_RAMFB && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_RAMFB))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("this QEMU does not support '%s' video device"), virDomainVideoTypeToString(video->type)); diff --git a/tests/qemuxml2argvdata/video-ramfb-display-device.x86_64-latest.args b/tests/qemuxml2argvdata/video-ramfb-display-device.x86_64-latest.args new file mode 100644 index 0000000000..b26db5d546 --- /dev/null +++ b/tests/qemuxml2argvdata/video-ramfb-display-device.x86_64-latest.args @@ -0,0 +1,38 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 1024 \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-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=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,\ +id=drive-ide0-0-0,cache=none \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1,\ +write-cache=on \ +-device ramfb,id=video0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/video-ramfb-display-device.xml b/tests/qemuxml2argvdata/video-ramfb-display-device.xml new file mode 100644 index 0000000000..4123dad372 --- /dev/null +++ b/tests/qemuxml2argvdata/video-ramfb-display-device.xml @@ -0,0 +1,29 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu>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='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none'/> + <source file='/var/lib/libvirt/images/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='ide' index='0'/> + <video> + <model type='ramfb' /> + </video> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index abff3d1c61..3004a26832 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2060,6 +2060,7 @@ mymain(void) QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS); DO_TEST_CAPS_LATEST("video-bochs-display-device"); + DO_TEST_CAPS_LATEST("video-ramfb-display-device"); DO_TEST("video-none-device", QEMU_CAPS_VNC); DO_TEST_PARSE_ERROR("video-invalid-multiple-devices", NONE); -- 2.21.0

The 'ramfb' attribute provides a framebuffer to the guest that can be used as a boot display for the vgpu Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- docs/formatdomain.html.in | 8 ++++ docs/schemas/domaincommon.rng | 5 +++ src/conf/domain_conf.c | 11 ++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 17 ++++++++- ...tdev-mdev-display-ramfb.x86_64-latest.args | 37 +++++++++++++++++++ .../hostdev-mdev-display-ramfb.xml | 33 +++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 8 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index a8afe36756..1d95f3bc39 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -4837,6 +4837,14 @@ <a href="#elementsGraphics">graphical framebuffer</a> in order to use this attribute, currently only supported with VNC, Spice and egl-headless graphics devices. + + <span class="since">Since version 5.8.0</span>, there is an optional + <code>ramfb</code> attribute for devices with + <code>model='vfio-pci'</code>. Supported values are either + <code>on</code> or <code>off</code> (default is 'off'). When + enabled, this attribute provides a memory framebuffer device to the + guest. This framebuffer will be used as a boot display when a vgpu + device is the primary display. <p> Note: There are also some implications on the usage of guest's address type depending on the <code>model</code> attribute, diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index e2cebb5739..5456c38230 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4756,6 +4756,11 @@ <value>vfio-ap</value> </choice> </attribute> + <optional> + <attribute name="ramfb"> + <ref name="virOnOff"/> + </attribute> + </optional> <optional> <attribute name="display"> <ref name="virOnOff"/> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 73840c327c..55ebb4e37d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8120,6 +8120,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, VIR_AUTOFREE(char *) backendStr = NULL; VIR_AUTOFREE(char *) model = NULL; VIR_AUTOFREE(char *) display = NULL; + VIR_AUTOFREE(char *) ramfb = NULL; /* @managed can be read from the xml document - it is always an * attribute of the toplevel element, no matter what type of @@ -8135,6 +8136,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, rawio = virXMLPropString(node, "rawio"); model = virXMLPropString(node, "model"); display = virXMLPropString(node, "display"); + ramfb = virXMLPropString(node, "ramfb"); /* @type is passed in from the caller rather than read from the * xml document, because it is specified in different places for @@ -8243,6 +8245,15 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, display); return -1; } + + if (ramfb && + (mdevsrc->ramfb = virTristateSwitchTypeFromString(ramfb)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown value '%s' for <hostdev> attribute " + "'ramfb'"), + ramfb); + return -1; + } } switch (def->source.subsys.type) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 89e5fc1de8..df02b096aa 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -262,6 +262,7 @@ struct _virDomainHostdevSubsysMediatedDev { int model; /* enum virMediatedDeviceModelType */ int display; /* virTristateSwitch */ char uuidstr[VIR_UUID_STRING_BUFLEN]; /* mediated device's uuid string */ + int ramfb; /* virTristateSwitch */ }; typedef enum { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 57ab70d35f..c0d986ea67 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5385,6 +5385,17 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager, return virBufferContentAndReset(&buf); } +static const char * +qemuBuildHostdevMdevModelTypeString(virDomainHostdevSubsysMediatedDevPtr mdev) +{ + /* when the 'ramfb' attribute is set, we must use the nohotplug variant + * rather than 'vfio-pci' */ + if (mdev->model == VIR_MDEV_MODEL_TYPE_VFIO_PCI && + mdev->ramfb == VIR_TRISTATE_SWITCH_ON) + return "vfio-pci-nohotplug"; + + return virMediatedDeviceModelTypeToString(mdev->model); +} char * qemuBuildHostdevMediatedDevStr(const virDomainDef *def, @@ -5399,7 +5410,7 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, if (!(mdevPath = virMediatedDeviceGetSysfsPath(mdevsrc->uuidstr))) return NULL; - dev_str = virMediatedDeviceModelTypeToString(mdevsrc->model); + dev_str = qemuBuildHostdevMdevModelTypeString(mdevsrc); if (!dev_str) return NULL; @@ -5417,6 +5428,10 @@ qemuBuildHostdevMediatedDevStr(const virDomainDef *def, if (dev->info->bootIndex) virBufferAsprintf(&buf, ",bootindex=%u", dev->info->bootIndex); + if (mdevsrc->ramfb == VIR_TRISTATE_SWITCH_ON) + virBufferAsprintf(&buf, ",ramfb=%s", + virTristateSwitchTypeToString(mdevsrc->ramfb)); + if (virBufferCheckError(&buf) < 0) return NULL; diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.x86_64-latest.args b/tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.x86_64-latest.args new file mode 100644 index 0000000000..30d2f83318 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest2 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest2/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest2/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest2/.config \ +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 \ +-overcommit mem-lock=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 \ +-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-nohotplug,id=hostdev0,\ +sysfsdev=/sys/bus/mdev/devices/53764d0e-85a0-42b4-af5c-2046b460b1dc,display=on,\ +bus=pci.0,addr=0x3,ramfb=on \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.xml b/tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.xml new file mode 100644 index 0000000000..2e7851b2b0 --- /dev/null +++ b/tests/qemuxml2argvdata/hostdev-mdev-display-ramfb.xml @@ -0,0 +1,33 @@ +<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> + <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' ramfb='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 3004a26832..ca6dc4595d 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1617,6 +1617,7 @@ mymain(void) DO_TEST_PARSE_ERROR("hostdev-mdev-display-missing-graphics", QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST_CAPS_LATEST("hostdev-mdev-display-ramfb"); DO_TEST_PARSE_ERROR("hostdev-vfio-zpci-wrong-arch", QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("hostdev-vfio-zpci", -- 2.21.0

ping series On Fri, 2019-09-13 at 16:20 -0500, Jonathon Jongsma wrote:
When the bochs display type was added, the capability was never checked. Add that check in the same place as the other video device capability checks.
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/qemu/qemu_process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 955ba4de4c..b93af966e2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5278,7 +5278,9 @@ qemuProcessStartValidateVideo(virDomainObjPtr vm, !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU)) || (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO && video->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW))) { + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW)) || + (video->type == VIR_DOMAIN_VIDEO_TYPE_BOCHS && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_BOCHS_DISPLAY))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("this QEMU does not support '%s' video device"), virDomainVideoTypeToString(video->type));

On 9/13/19 5:20 PM, Jonathon Jongsma wrote:
When the bochs display type was added, the capability was never checked. Add that check in the same place as the other video device capability checks.
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/qemu/qemu_process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 955ba4de4c..b93af966e2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5278,7 +5278,9 @@ qemuProcessStartValidateVideo(virDomainObjPtr vm, !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU)) || (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO && video->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW))) { + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW)) || + (video->type == VIR_DOMAIN_VIDEO_TYPE_BOCHS && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_BOCHS_DISPLAY))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("this QEMU does not support '%s' video device"), virDomainVideoTypeToString(video->type));
For 1-3: Reviewed-by: Cole Robinson <crobinso@redhat.com> I rebased, adjusted the 5.8.0 references and pushed. Since patch #4 is adding a new XML element, can you rebase and send, but with the new XML in the commit message? You can CC me and I'll review it, but let it sit for a bit incase anyone else has comments on the new XML Some general comments: * Not sure if it's a rule around here, but I suggest always sending a cover letter for > 1 patches. Personally for me an upfront summary can help reduce cognitive load of the series, I have an idea of where it is going without having to look at every patch to figure it out. * Please do for 'ramfb' what fabiano did for bochs-display here: https://www.redhat.com/archives/libvir-list/2019-October/msg00123.html Otherwise apps don't have a good way to determine if ramfb is supported or not. Sidenote: Better still, you can unify the validate code and domcaps code using an approach like I added for RNG here: https://www.redhat.com/archives/libvir-list/2019-April/msg00457.html Starting point would be to fold the whole qemuProcessStartValidateVideo to be part of qemuDomainDeviceDefValidateVideo. It's only at ProcessStart time for historical reasons IIRC, back when we didn't have proper infrastructure for the Validate path that wouldn't make VMs disappear on libvirtd restart. CCing fidencio too who I've talked about this last bit in private, and pmores who is working on nearby code currently. I promise timely reviews for anyone who works on this and CCs me :) - Cole
participants (2)
-
Cole Robinson
-
Jonathon Jongsma