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 @@