diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 1a7eeaefbe..9c1d0f406e 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -4732,7 +4732,10 @@ qemu-kvm -net nic,model=? /dev/null only and specifies the size of the primary bar, while the optional attribute vram specifies the secondary bar size. If "ram" or "vram" are not supplied a default value is used. The ram - should also be rounded to power of two as vram. + should also be rounded to power of two as vram. There is also optional + attribute vgamem (since 1.2.11 (QEMU + only)) to set the size of VGA framebuffer for fallback mode of + QXL device.

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index ae5c253a63..cd354854ee 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2877,6 +2877,11 @@ + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f187ee78d2..870cca0530 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10272,6 +10272,7 @@ virDomainVideoDefParseXML(xmlNodePtr node, char *heads = NULL; char *vram = NULL; char *ram = NULL; + char *vgamem = NULL; char *primary = NULL; if (VIR_ALLOC(def) < 0) @@ -10285,6 +10286,7 @@ virDomainVideoDefParseXML(xmlNodePtr node, type = virXMLPropString(cur, "type"); ram = virXMLPropString(cur, "ram"); vram = virXMLPropString(cur, "vram"); + vgamem = virXMLPropString(cur, "vgamem"); heads = virXMLPropString(cur, "heads"); if ((primary = virXMLPropString(cur, "primary")) != NULL) { @@ -10338,6 +10340,19 @@ virDomainVideoDefParseXML(xmlNodePtr node, def->vram = virDomainVideoDefaultRAM(dom, def->type); } + if (vgamem) { + if (def->type != VIR_DOMAIN_VIDEO_TYPE_QXL) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("vgamem attribute only supported for type of qxl")); + goto error; + } + if (virStrToLong_ui(vgamem, NULL, 10, &def->vgamem) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("cannot parse video vgamem '%s'"), vgamem); + goto error; + } + } + if (heads) { if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -10354,6 +10369,7 @@ virDomainVideoDefParseXML(xmlNodePtr node, VIR_FREE(type); VIR_FREE(ram); VIR_FREE(vram); + VIR_FREE(vgamem); VIR_FREE(heads); return def; @@ -10363,6 +10379,7 @@ virDomainVideoDefParseXML(xmlNodePtr node, VIR_FREE(type); VIR_FREE(ram); VIR_FREE(vram); + VIR_FREE(vgamem); VIR_FREE(heads); return NULL; } @@ -14739,6 +14756,13 @@ virDomainVideoDefCheckABIStability(virDomainVideoDefPtr src, return false; } + if (src->vgamem != dst->vgamem) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target video card vgamem %u does not match source %u"), + dst->vgamem, src->vgamem); + return false; + } + if (src->heads != dst->heads) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target video card heads %u does not match source %u"), @@ -18119,6 +18143,8 @@ virDomainVideoDefFormat(virBufferPtr buf, virBufferAsprintf(buf, " ram='%u'", def->ram); if (def->vram) virBufferAsprintf(buf, " vram='%u'", def->vram); + if (def->vgamem) + virBufferAsprintf(buf, " vgamem='%u'", def->vgamem); if (def->heads) virBufferAsprintf(buf, " heads='%u'", def->heads); if (def->primary) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ffe1be6570..d4284514e1 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1293,6 +1293,7 @@ struct _virDomainVideoDef { int type; unsigned int ram; /* kibibytes (multiples of 1024) */ unsigned int vram; /* kibibytes (multiples of 1024) */ + unsigned int vgamem; /* kibibytes (multiples of 1024) */ unsigned int heads; bool primary; virDomainVideoAccelDefPtr accel; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1003a0d418..4ed6506483 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4911,6 +4911,12 @@ qemuBuildDeviceVideoStr(virDomainDefPtr def, /* QEMU accepts bytes for vram_size. */ virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024); } + + if ((primary && virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM)) || + (!primary && virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGAMEM))) { + /* QEMU accepts mebibytes for vgamem_mb. */ + virBufferAsprintf(&buf, ",vgamem_mb=%u", video->vgamem / 1024); + } } else if (video->vram && ((video->type == VIR_DOMAIN_VIDEO_TYPE_VGA && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_VGAMEM)) || @@ -9244,6 +9250,7 @@ qemuBuildCommandLine(virConnectPtr conn, virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { unsigned int ram = def->videos[0]->ram; unsigned int vram = def->videos[0]->vram; + unsigned int vgamem = def->videos[0]->vgamem; if (vram > (UINT_MAX / 1024)) { virReportError(VIR_ERR_OVERFLOW, @@ -9268,6 +9275,12 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArgFormat(cmd, "%s.vram_size=%u", dev, vram * 1024); } + if (vgamem && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM)) { + virCommandAddArg(cmd, "-global"); + virCommandAddArgFormat(cmd, "%s.vgamem_mb=%u", + dev, vgamem / 1024); + } } if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && @@ -12284,8 +12297,13 @@ qemuParseCommandLine(virCapsPtr qemuCaps, else vid->type = video; vid->vram = virDomainVideoDefaultRAM(def, vid->type); - vid->ram = vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL ? - virDomainVideoDefaultRAM(def, vid->type) : 0; + if (vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL) { + vid->ram = virDomainVideoDefaultRAM(def, vid->type); + vid->vgamem = 8 * 1024; + } else { + vid->ram = 0; + vid->vgamem = 0; + } vid->heads = 1; if (VIR_APPEND_ELEMENT(def->videos, def->nvideos, vid) < 0) { diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 01bf39b480..334bd407d9 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1176,6 +1176,25 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, goto cleanup; } + if (dev->type == VIR_DOMAIN_DEVICE_VIDEO && + dev->data.video->type == VIR_DOMAIN_VIDEO_TYPE_QXL) { + if (dev->data.video->vgamem) { + if (dev->data.video->vgamem < 1024) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("value for 'vgamem' must be at least 1 MiB " + "(1024 KiB)")); + goto cleanup; + } + if (dev->data.video->vgamem != VIR_ROUND_UP_POWER_OF_TWO(dev->data.video->vgamem)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("value for 'vgamem' must be power of two")); + goto cleanup; + } + } else { + dev->data.video->vgamem = 8 * 1024; + } + } + ret = 0; cleanup: diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml index 5c9683f9cb..c13327ad0b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml @@ -33,10 +33,10 @@ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml index acf301985f..ac705f330a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml @@ -30,10 +30,10 @@ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml index 335ce69c52..0c61ee5cf1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml @@ -37,10 +37,10 @@ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.xml b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.xml index 168b2701bb..ef9cd4fd8c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.xml @@ -26,7 +26,7 @@ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35.xml index 02df713771..05967a409c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35.xml @@ -23,7 +23,7 @@ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.xml index 905924eaae..1127db10c0 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.xml @@ -37,7 +37,7 @@ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vgamem.args b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vgamem.args index c9eb53578b..5398ffe014 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vgamem.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vgamem.args @@ -2,5 +2,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ /usr/bin/qemu -S -M pc -m 1024 -smp 1 -nographic -nodefaults \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -hda /var/lib/libvirt/images/QEMUGuest1 \ --device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0\ -,addr=0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=8\ +,bus=pci.0,addr=0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vgamem.args b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vgamem.args index 5fc41bbfa2..82aa0a9d23 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vgamem.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vgamem.args @@ -2,7 +2,7 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ /usr/bin/qemu -S -M pc -m 1024 -smp 1 -nographic -nodefaults \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -hda /var/lib/libvirt/images/QEMUGuest1 \ --device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0\ -,addr=0x2 -device qxl,id=video1,ram_size=67108864,vram_size=67108864,bus=pci.0\ -,addr=0x4 \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=8\ +,bus=pci.0,addr=0x2 -device qxl,id=video1,ram_size=67108864,vram_size=67108864\ +,vgamem_mb=8,bus=pci.0,addr=0x4 \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 315e1f4140..c7b8ecf2bd 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1362,13 +1362,15 @@ mymain(void) DO_TEST("video-qxl-device", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_QXL_VGA, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); DO_TEST("video-qxl-device-vgamem", QEMU_CAPS_DEVICE, - QEMU_CAPS_DEVICE_QXL_VGA, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); + QEMU_CAPS_DEVICE_QXL_VGA, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_QXL_VGA_VGAMEM); DO_TEST_FAILURE("video-qxl-sec-nodevice", QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL); DO_TEST("video-qxl-sec-device", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_QXL_VGA, QEMU_CAPS_DEVICE_QXL, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); DO_TEST("video-qxl-sec-device-vgamem", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_QXL_VGA, QEMU_CAPS_DEVICE_QXL, - QEMU_CAPS_DEVICE_VIDEO_PRIMARY); + QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_QXL_VGA_VGAMEM, + QEMU_CAPS_QXL_VGAMEM); DO_TEST("virtio-rng-default", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_VIRTIO_RNG, QEMU_CAPS_OBJECT_RNG_RANDOM); diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml index 752c7d504a..9dd41623ed 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml @@ -24,7 +24,7 @@