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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list