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