two as <code>vram</code>. There is also optional attribute
<code>vgamem</code> (<span class="since">since 1.2.11</span>) to set
the size of VGA framebuffer for fallback mode of QXL device.
+ Attribute <code>vram64</code> (<span class="since">since 1.3.2</span>)
+ extends secondary bar and makes it addressable as 64bit memory.
</p>
</dd>
<ref name="unsignedInt"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="vram64">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
</group>
</choice>
<optional>
char *type = NULL;
char *heads = NULL;
char *vram = NULL;
+ char *vram64 = NULL;
char *ram = NULL;
char *vgamem = NULL;
char *primary = NULL;
type = virXMLPropString(cur, "type");
ram = virXMLPropString(cur, "ram");
vram = virXMLPropString(cur, "vram");
+ vram64 = virXMLPropString(cur, "vram64");
vgamem = virXMLPropString(cur, "vgamem");
heads = virXMLPropString(cur, "heads");
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",
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);
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
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"),
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)
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;
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 &&
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)) {
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");
}
+/**
+ * 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,
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,
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'"),
}
+/**
+ * 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)
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,
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:
--- /dev/null
+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
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2' cache='none'/>
+ <source file='/var/lib/libvirt/images/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <video>
+ <model type='qxl' vram64='131072' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+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
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2' cache='none'/>
+ <source file='/var/lib/libvirt/images/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <video>
+ <model type='qxl' heads='1'/>
+ </video>
+ <video>
+ <model type='qxl' vram64='131072' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>