qemu-command: introduce new vgamem attribute for QXL video device

Add attribute to set vgamem_mb parameter of QXL device for QEMU. This
value sets the size of VGA framebuffer for QXL device. Default value in
QEMU is 8MB so reuse it also in libvirt to not break things.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1076098

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Pavel Hrdina 2014-11-20 19:52:00 +01:00
parent 24c6ca860e
commit 742d49fa17
16 changed files with 94 additions and 20 deletions

View File

@ -4732,7 +4732,10 @@ qemu-kvm -net nic,model=? /dev/null
only and specifies the size of the primary bar, while the optional only and specifies the size of the primary bar, while the optional
attribute <code>vram</code> specifies the secondary bar size. attribute <code>vram</code> specifies the secondary bar size.
If "ram" or "vram" are not supplied a default value is used. The ram 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 <code>vgamem</code> (<span class="since">since 1.2.11 (QEMU
only)</span>) to set the size of VGA framebuffer for fallback mode of
QXL device.
</p> </p>
</dd> </dd>

View File

@ -2877,6 +2877,11 @@
<ref name="unsignedInt"/> <ref name="unsignedInt"/>
</attribute> </attribute>
</optional> </optional>
<optional>
<attribute name="vgamem">
<ref name="unsignedInt"/>
</attribute>
</optional>
</group> </group>
</choice> </choice>
<optional> <optional>

View File

@ -10272,6 +10272,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
char *heads = NULL; char *heads = NULL;
char *vram = NULL; char *vram = NULL;
char *ram = NULL; char *ram = NULL;
char *vgamem = NULL;
char *primary = NULL; char *primary = NULL;
if (VIR_ALLOC(def) < 0) if (VIR_ALLOC(def) < 0)
@ -10285,6 +10286,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
type = virXMLPropString(cur, "type"); type = virXMLPropString(cur, "type");
ram = virXMLPropString(cur, "ram"); ram = virXMLPropString(cur, "ram");
vram = virXMLPropString(cur, "vram"); vram = virXMLPropString(cur, "vram");
vgamem = virXMLPropString(cur, "vgamem");
heads = virXMLPropString(cur, "heads"); heads = virXMLPropString(cur, "heads");
if ((primary = virXMLPropString(cur, "primary")) != NULL) { if ((primary = virXMLPropString(cur, "primary")) != NULL) {
@ -10338,6 +10340,19 @@ virDomainVideoDefParseXML(xmlNodePtr node,
def->vram = virDomainVideoDefaultRAM(dom, def->type); 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 (heads) {
if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) { if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
@ -10354,6 +10369,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
VIR_FREE(type); VIR_FREE(type);
VIR_FREE(ram); VIR_FREE(ram);
VIR_FREE(vram); VIR_FREE(vram);
VIR_FREE(vgamem);
VIR_FREE(heads); VIR_FREE(heads);
return def; return def;
@ -10363,6 +10379,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
VIR_FREE(type); VIR_FREE(type);
VIR_FREE(ram); VIR_FREE(ram);
VIR_FREE(vram); VIR_FREE(vram);
VIR_FREE(vgamem);
VIR_FREE(heads); VIR_FREE(heads);
return NULL; return NULL;
} }
@ -14739,6 +14756,13 @@ virDomainVideoDefCheckABIStability(virDomainVideoDefPtr src,
return false; 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) { if (src->heads != dst->heads) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target video card heads %u does not match source %u"), _("Target video card heads %u does not match source %u"),
@ -18119,6 +18143,8 @@ virDomainVideoDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " ram='%u'", def->ram); virBufferAsprintf(buf, " ram='%u'", def->ram);
if (def->vram) if (def->vram)
virBufferAsprintf(buf, " vram='%u'", def->vram); virBufferAsprintf(buf, " vram='%u'", def->vram);
if (def->vgamem)
virBufferAsprintf(buf, " vgamem='%u'", def->vgamem);
if (def->heads) if (def->heads)
virBufferAsprintf(buf, " heads='%u'", def->heads); virBufferAsprintf(buf, " heads='%u'", def->heads);
if (def->primary) if (def->primary)

View File

@ -1293,6 +1293,7 @@ struct _virDomainVideoDef {
int type; int type;
unsigned int ram; /* kibibytes (multiples of 1024) */ unsigned int ram; /* kibibytes (multiples of 1024) */
unsigned int vram; /* kibibytes (multiples of 1024) */ unsigned int vram; /* kibibytes (multiples of 1024) */
unsigned int vgamem; /* kibibytes (multiples of 1024) */
unsigned int heads; unsigned int heads;
bool primary; bool primary;
virDomainVideoAccelDefPtr accel; virDomainVideoAccelDefPtr accel;

View File

@ -4911,6 +4911,12 @@ qemuBuildDeviceVideoStr(virDomainDefPtr def,
/* QEMU accepts bytes for vram_size. */ /* QEMU accepts bytes for vram_size. */
virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024); 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 && } else if (video->vram &&
((video->type == VIR_DOMAIN_VIDEO_TYPE_VGA && ((video->type == VIR_DOMAIN_VIDEO_TYPE_VGA &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_VGAMEM)) || virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_VGAMEM)) ||
@ -9244,6 +9250,7 @@ qemuBuildCommandLine(virConnectPtr conn,
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
unsigned int ram = def->videos[0]->ram; unsigned int ram = def->videos[0]->ram;
unsigned int vram = def->videos[0]->vram; unsigned int vram = def->videos[0]->vram;
unsigned int vgamem = def->videos[0]->vgamem;
if (vram > (UINT_MAX / 1024)) { if (vram > (UINT_MAX / 1024)) {
virReportError(VIR_ERR_OVERFLOW, virReportError(VIR_ERR_OVERFLOW,
@ -9268,6 +9275,12 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArgFormat(cmd, "%s.vram_size=%u", virCommandAddArgFormat(cmd, "%s.vram_size=%u",
dev, vram * 1024); 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) && if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
@ -12284,8 +12297,13 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
else else
vid->type = video; vid->type = video;
vid->vram = virDomainVideoDefaultRAM(def, vid->type); vid->vram = virDomainVideoDefaultRAM(def, vid->type);
vid->ram = vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL ? if (vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL) {
virDomainVideoDefaultRAM(def, vid->type) : 0; vid->ram = virDomainVideoDefaultRAM(def, vid->type);
vid->vgamem = 8 * 1024;
} else {
vid->ram = 0;
vid->vgamem = 0;
}
vid->heads = 1; vid->heads = 1;
if (VIR_APPEND_ELEMENT(def->videos, def->nvideos, vid) < 0) { if (VIR_APPEND_ELEMENT(def->videos, def->nvideos, vid) < 0) {

View File

@ -1176,6 +1176,25 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
goto cleanup; 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; ret = 0;
cleanup: cleanup:

View File

@ -33,10 +33,10 @@
<streaming mode='filter'/> <streaming mode='filter'/>
</graphics> </graphics>
<video> <video>
<model type='qxl' ram='65536' vram='32768' heads='1'/> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
</video> </video>
<video> <video>
<model type='qxl' ram='65536' vram='32768' heads='1'/> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
</video> </video>
<memballoon model='virtio'/> <memballoon model='virtio'/>
</devices> </devices>

View File

@ -30,10 +30,10 @@
<channel name='inputs' mode='insecure'/> <channel name='inputs' mode='insecure'/>
</graphics> </graphics>
<video> <video>
<model type='qxl' ram='65536' vram='32768' heads='1'/> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
</video> </video>
<video> <video>
<model type='qxl' ram='65536' vram='65536' heads='1'/> <model type='qxl' ram='65536' vram='65536' vgamem='8192' heads='1'/>
</video> </video>
<memballoon model='virtio'/> <memballoon model='virtio'/>
</devices> </devices>

View File

@ -37,10 +37,10 @@
<filetransfer enable='no'/> <filetransfer enable='no'/>
</graphics> </graphics>
<video> <video>
<model type='qxl' ram='65536' vram='32768' heads='1'/> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
</video> </video>
<video> <video>
<model type='qxl' ram='65536' vram='32768' heads='1'/> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
</video> </video>
<memballoon model='virtio'/> <memballoon model='virtio'/>
</devices> </devices>

View File

@ -26,7 +26,7 @@
<controller type='pci' index='2' model='pci-bridge'/> <controller type='pci' index='2' model='pci-bridge'/>
<controller type='sata' index='0'/> <controller type='sata' index='0'/>
<video> <video>
<model type='qxl' ram='65536' vram='32768' heads='1'/> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
</video> </video>
<memballoon model='none'/> <memballoon model='none'/>
</devices> </devices>

View File

@ -23,7 +23,7 @@
<controller type='pci' index='1' model='dmi-to-pci-bridge'/> <controller type='pci' index='1' model='dmi-to-pci-bridge'/>
<controller type='pci' index='2' model='pci-bridge'/> <controller type='pci' index='2' model='pci-bridge'/>
<video> <video>
<model type='qxl' ram='65536' vram='32768' heads='1'/> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
</video> </video>
<memballoon model='none'/> <memballoon model='none'/>
</devices> </devices>

View File

@ -37,7 +37,7 @@
<listen type='address' address='127.0.0.1'/> <listen type='address' address='127.0.0.1'/>
</graphics> </graphics>
<video> <video>
<model type='qxl' ram='65536' vram='65536' heads='1'/> <model type='qxl' ram='65536' vram='65536' vgamem='8192' heads='1'/>
</video> </video>
<memballoon model='virtio'/> <memballoon model='virtio'/>
</devices> </devices>

View File

@ -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 \ /usr/bin/qemu -S -M pc -m 1024 -smp 1 -nographic -nodefaults \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
-hda /var/lib/libvirt/images/QEMUGuest1 \ -hda /var/lib/libvirt/images/QEMUGuest1 \
-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0\ -device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=8\
,addr=0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 ,bus=pci.0,addr=0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -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 \ /usr/bin/qemu -S -M pc -m 1024 -smp 1 -nographic -nodefaults \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
-hda /var/lib/libvirt/images/QEMUGuest1 \ -hda /var/lib/libvirt/images/QEMUGuest1 \
-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0\ -device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=8\
,addr=0x2 -device qxl,id=video1,ram_size=67108864,vram_size=67108864,bus=pci.0\ ,bus=pci.0,addr=0x2 -device qxl,id=video1,ram_size=67108864,vram_size=67108864\
,addr=0x4 \ ,vgamem_mb=8,bus=pci.0,addr=0x4 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -1362,13 +1362,15 @@ mymain(void)
DO_TEST("video-qxl-device", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_QXL_VGA, DO_TEST("video-qxl-device", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_QXL_VGA,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY); QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
DO_TEST("video-qxl-device-vgamem", QEMU_CAPS_DEVICE, 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_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, DO_TEST("video-qxl-sec-device", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_QXL_VGA,
QEMU_CAPS_DEVICE_QXL, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); QEMU_CAPS_DEVICE_QXL, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
DO_TEST("video-qxl-sec-device-vgamem", QEMU_CAPS_DEVICE, DO_TEST("video-qxl-sec-device-vgamem", QEMU_CAPS_DEVICE,
QEMU_CAPS_DEVICE_QXL_VGA, QEMU_CAPS_DEVICE_QXL, 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, DO_TEST("virtio-rng-default", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_VIRTIO_RNG,
QEMU_CAPS_OBJECT_RNG_RANDOM); QEMU_CAPS_OBJECT_RNG_RANDOM);

View File

@ -24,7 +24,7 @@
<controller type='pci' index='2' model='pci-bridge'/> <controller type='pci' index='2' model='pci-bridge'/>
<controller type='sata' index='0'/> <controller type='sata' index='0'/>
<video> <video>
<model type='qxl' ram='65536' vram='32768' heads='1'/> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
</video> </video>
<memballoon model='none'/> <memballoon model='none'/>
</devices> </devices>