diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 07248e113e..360410913d 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5200,6 +5200,8 @@ qemu-kvm -net nic,model=? /dev/null two as vram. There is also optional attribute vgamem (since 1.2.11) to set the size of VGA framebuffer for fallback mode of QXL device. + Attribute vram64 (since 1.3.2) + extends secondary bar and makes it addressable as 64bit memory.

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 18ef51092e..4e57394737 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2946,6 +2946,11 @@ + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1f6bc75f30..7d7594e89f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11918,6 +11918,7 @@ virDomainVideoDefParseXML(xmlNodePtr node, char *type = NULL; char *heads = NULL; char *vram = NULL; + char *vram64 = NULL; char *ram = NULL; char *vgamem = NULL; char *primary = NULL; @@ -11933,6 +11934,7 @@ virDomainVideoDefParseXML(xmlNodePtr node, type = virXMLPropString(cur, "type"); ram = virXMLPropString(cur, "ram"); vram = virXMLPropString(cur, "vram"); + vram64 = virXMLPropString(cur, "vram64"); vgamem = virXMLPropString(cur, "vgamem"); heads = virXMLPropString(cur, "heads"); @@ -11987,6 +11989,19 @@ virDomainVideoDefParseXML(xmlNodePtr node, def->vram = virDomainVideoDefaultRAM(dom, def->type); } + if (vram64) { + if (def->type != VIR_DOMAIN_VIDEO_TYPE_QXL) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("vram64 attribute only supported for type of qxl")); + goto error; + } + if (virStrToLong_uip(vram64, NULL, 10, &def->vram64) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("cannot parse video vram64 '%s'"), vram64); + goto error; + } + } + if (vgamem) { if (def->type != VIR_DOMAIN_VIDEO_TYPE_QXL) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -12013,9 +12028,11 @@ virDomainVideoDefParseXML(xmlNodePtr node, if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; + cleanup: VIR_FREE(type); VIR_FREE(ram); VIR_FREE(vram); + VIR_FREE(vram64); VIR_FREE(vgamem); VIR_FREE(heads); @@ -12023,12 +12040,8 @@ virDomainVideoDefParseXML(xmlNodePtr node, error: virDomainVideoDefFree(def); - VIR_FREE(type); - VIR_FREE(ram); - VIR_FREE(vram); - VIR_FREE(vgamem); - VIR_FREE(heads); - return NULL; + def = NULL; + goto cleanup; } static virDomainHostdevDefPtr @@ -17041,6 +17054,13 @@ virDomainVideoDefCheckABIStability(virDomainVideoDefPtr src, return false; } + if (src->vram64 != dst->vram64) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target video card vram64 %u does not match source %u"), + dst->vram64, src->vram64); + return false; + } + if (src->vgamem != dst->vgamem) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target video card vgamem %u does not match source %u"), @@ -20726,6 +20746,8 @@ virDomainVideoDefFormat(virBufferPtr buf, virBufferAsprintf(buf, " ram='%u'", def->ram); if (def->vram) virBufferAsprintf(buf, " vram='%u'", def->vram); + if (def->vram64) + virBufferAsprintf(buf, " vram64='%u'", def->vram64); if (def->vgamem) virBufferAsprintf(buf, " vgamem='%u'", def->vgamem); if (def->heads) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d3b3ed289e..7e437fa90f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1399,6 +1399,7 @@ struct _virDomainVideoDef { int type; unsigned int ram; /* kibibytes (multiples of 1024) */ unsigned int vram; /* kibibytes (multiples of 1024) */ + unsigned int vram64; /* kibibytes (multiples of 1024) */ unsigned int vgamem; /* kibibytes (multiples of 1024) */ unsigned int heads; bool primary; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 7864b98b9f..0680478643 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3346,6 +3346,14 @@ qemuBuildDeviceVideoStr(virDomainDefPtr def, virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024); } + if ((video->primary && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VRAM64)) || + (!video->primary && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VRAM64))) { + /* QEMU accepts mebibytes for vram64_size_mb. */ + virBufferAsprintf(&buf, ",vram64_size_mb=%u", video->vram64 / 1024); + } + if ((video->primary && virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM)) || (!video->primary && @@ -8272,6 +8280,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 vram64 = def->videos[0]->vram64; unsigned int vgamem = def->videos[0]->vgamem; if (vram > (UINT_MAX / 1024)) { @@ -8297,6 +8306,12 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArgFormat(cmd, "%s.vram_size=%u", dev, vram * 1024); } + if (vram64 && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VRAM64)) { + virCommandAddArg(cmd, "-global"); + virCommandAddArgFormat(cmd, "%s.vram64_size_mb=%u", + dev, vram64 / 1024); + } if (vgamem && virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM)) { virCommandAddArg(cmd, "-global"); diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index cb87412a8d..ace3bb4af2 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1154,6 +1154,41 @@ qemuMonitorUpdateVideoMemorySize(qemuMonitorPtr mon, } +/** + * To update video vram64 size in status XML we need to load correct value from + * QEMU. This is supported only with JSON monitor. + * + * Returns 0 on success, -1 on failure and sets proper error message. + */ +int +qemuMonitorUpdateVideoVram64Size(qemuMonitorPtr mon, + virDomainVideoDefPtr video, + const char *videoName) +{ + int ret = -1; + char *path = NULL; + + QEMU_CHECK_MONITOR(mon); + + if (mon->json) { + ret = qemuMonitorJSONFindLinkPath(mon, videoName, &path); + if (ret < 0) { + if (ret == -2) + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to find QOM Object path for " + "device '%s'"), videoName); + return -1; + } + + ret = qemuMonitorJSONUpdateVideoVram64Size(mon, video, path); + VIR_FREE(path); + return ret; + } + + return 0; +} + + int qemuMonitorHMPCommandWithFd(qemuMonitorPtr mon, const char *cmd, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6a2a985ad8..4467a4180b 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -269,6 +269,10 @@ int qemuMonitorUpdateVideoMemorySize(qemuMonitorPtr mon, virDomainVideoDefPtr video, const char *videoName) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +int qemuMonitorUpdateVideoVram64Size(qemuMonitorPtr mon, + virDomainVideoDefPtr video, + const char *videoName) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); int qemuMonitorHMPCommandWithFd(qemuMonitorPtr mon, const char *cmd, int scm_fd, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index d2b641fc67..8352e53ffd 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1436,6 +1436,18 @@ qemuMonitorJSONUpdateVideoMemorySize(qemuMonitorPtr mon, return -1; } video->vram = prop.val.ul / 1024; + + if (video->vram64 != 0) { + if (qemuMonitorJSONGetObjectProperty(mon, path, + "vram64_size_mb", &prop) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("QOM Object '%s' has no property 'vram64_size_mb'"), + path); + return -1; + } + video->vram64 = prop.val.ul / 1024; + } + if (qemuMonitorJSONGetObjectProperty(mon, path, "ram_size", &prop) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("QOM Object '%s' has no property 'ram_size'"), @@ -1471,6 +1483,48 @@ qemuMonitorJSONUpdateVideoMemorySize(qemuMonitorPtr mon, } +/** + * Loads correct video vram64 size value from QEMU and update the video + * definition. + * + * Return 0 on success, -1 on failure and set proper error message. + */ +int +qemuMonitorJSONUpdateVideoVram64Size(qemuMonitorPtr mon, + virDomainVideoDefPtr video, + char *path) +{ + qemuMonitorJSONObjectProperty prop = { + QEMU_MONITOR_OBJECT_PROPERTY_ULONG, + {0} + }; + + switch (video->type) { + case VIR_DOMAIN_VIDEO_TYPE_QXL: + if (video->vram64 != 0) { + if (qemuMonitorJSONGetObjectProperty(mon, path, + "vram64_size_mb", &prop) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("QOM Object '%s' has no property 'vram64_size_mb'"), + path); + return -1; + } + video->vram64 = prop.val.ul / 1024; + } + break; + case VIR_DOMAIN_VIDEO_TYPE_VGA: + case VIR_DOMAIN_VIDEO_TYPE_VMVGA: + case VIR_DOMAIN_VIDEO_TYPE_CIRRUS: + case VIR_DOMAIN_VIDEO_TYPE_XEN: + case VIR_DOMAIN_VIDEO_TYPE_VBOX: + case VIR_DOMAIN_VIDEO_TYPE_LAST: + break; + } + + return 0; +} + + int qemuMonitorJSONGetBalloonInfo(qemuMonitorPtr mon, unsigned long long *currmem) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 2c27c6f9c7..4068187c40 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -60,6 +60,9 @@ int qemuMonitorJSONGetVirtType(qemuMonitorPtr mon, int qemuMonitorJSONUpdateVideoMemorySize(qemuMonitorPtr mon, virDomainVideoDefPtr video, char *path); +int qemuMonitorJSONUpdateVideoVram64Size(qemuMonitorPtr mon, + virDomainVideoDefPtr video, + char *path); int qemuMonitorJSONGetBalloonInfo(qemuMonitorPtr mon, unsigned long long *currmem); int qemuMonitorJSONGetMemoryStats(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7d8cf9d3cd..ded20b157c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2740,17 +2740,25 @@ qemuProcessUpdateVideoRamSize(virQEMUDriverPtr driver, break; case VIR_DOMAIN_VIDEO_TYPE_QXL: if (i == 0) { - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM)) { - if (qemuMonitorUpdateVideoMemorySize(priv->mon, video, - "qxl-vga") < 0) + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM) && + qemuMonitorUpdateVideoMemorySize(priv->mon, video, + "qxl-vga") < 0) goto error; - } + + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGA_VRAM64) && + qemuMonitorUpdateVideoVram64Size(priv->mon, video, + "qxl-vga") < 0) + goto error; } else { - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGAMEM)) { - if (qemuMonitorUpdateVideoMemorySize(priv->mon, video, - "qxl") < 0) + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGAMEM) && + qemuMonitorUpdateVideoMemorySize(priv->mon, video, + "qxl") < 0) + goto error; + + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VRAM64) && + qemuMonitorUpdateVideoVram64Size(priv->mon, video, + "qxl") < 0) goto error; - } } break; case VIR_DOMAIN_VIDEO_TYPE_VMVGA: diff --git a/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vram64.args b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vram64.args new file mode 100644 index 0000000000..b9e65ea873 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vram64.args @@ -0,0 +1,25 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 1024 \ +-smp 1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,\ +id=drive-ide0-0-0,cache=none \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,\ +vram64_size_mb=128,vgamem_mb=16,bus=pci.0,addr=0x2 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vram64.xml b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vram64.xml new file mode 100644 index 0000000000..1e89d06a75 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-device-vram64.xml @@ -0,0 +1,29 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 1048576 + 1048576 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + + +
+ + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vram64.args b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vram64.args new file mode 100644 index 0000000000..fadc3ed811 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vram64.args @@ -0,0 +1,27 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 1024 \ +-smp 1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,\ +id=drive-ide0-0-0,cache=none \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=16,\ +bus=pci.0,addr=0x2 \ +-device qxl,id=video1,ram_size=67108864,vram_size=67108864,vram64_size_mb=128,\ +vgamem_mb=16,bus=pci.0,addr=0x4 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vram64.xml b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vram64.xml new file mode 100644 index 0000000000..72e8bad7a7 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-video-qxl-sec-device-vram64.xml @@ -0,0 +1,32 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 1048576 + 1048576 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + + + + + +