From: Zeng Junliang <zengjunliang(a)huawei.com>
This patch introduces vgamem attribute for video model, and sets
its default value as qemu used. Parse it in two ways accroding to
qemu startup parameters supported: -device or -vga.
Signed-off-by: Zeng Junliang <zengjunliang(a)huawei.com>
Signed-off-by: Wang Rui <moon.wangrui(a)huawei.com>
---
src/conf/domain_conf.c | 48 ++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 3 +-
src/libvirt_private.syms | 1 +
src/qemu/qemu_command.c | 75 ++++++++++++++++++++++++++++++++----------------
4 files changed, 101 insertions(+), 26 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 63d97ec..d5a65c3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9328,6 +9328,20 @@ virDomainVideoDefaultRAM(const virDomainDef *def,
}
}
+int
+virDomainVideoDefaultVgamem(int type)
+{
+ switch (type) {
+ case VIR_DOMAIN_VIDEO_TYPE_VGA:
+ case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
+ case VIR_DOMAIN_VIDEO_TYPE_QXL:
+ /* QEMU use 16M as default value for vga/vmvga/qxl device*/
+ return 16 * 1024;
+
+ default:
+ return 0;
+ }
+}
int
virDomainVideoDefaultType(const virDomainDef *def)
@@ -9413,6 +9427,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
char *type = NULL;
char *heads = NULL;
char *vram = NULL;
+ char *vgamem = NULL;
char *ram = NULL;
char *primary = NULL;
@@ -9422,11 +9437,12 @@ virDomainVideoDefParseXML(xmlNodePtr node,
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
- if (!type && !vram && !ram && !heads &&
+ if (!type && !vram && !ram && !heads &&
!vgamem &&
xmlStrEqual(cur->name, BAD_CAST "model")) {
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) {
@@ -9490,6 +9506,24 @@ virDomainVideoDefParseXML(xmlNodePtr node,
def->vram = virDomainVideoDefaultRAM(dom, def->type);
}
+ if (vgamem) {
+ if (def->type != VIR_DOMAIN_VIDEO_TYPE_VGA &&
+ def->type != VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
+ def->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("vgamem attribute only supported "
+ "for type of vga, vmvga and 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;
+ }
+ } else {
+ def->vgamem = virDomainVideoDefaultVgamem(def->type);
+ }
+
if (heads) {
if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -9506,6 +9540,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
VIR_FREE(type);
VIR_FREE(ram);
VIR_FREE(vram);
+ VIR_FREE(vgamem);
VIR_FREE(heads);
return def;
@@ -9515,6 +9550,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
VIR_FREE(type);
VIR_FREE(ram);
VIR_FREE(vram);
+ VIR_FREE(vgamem);
VIR_FREE(heads);
return NULL;
}
@@ -12636,6 +12672,7 @@ virDomainDefParseXML(xmlDocPtr xml,
VIR_FREE(video);
goto error;
}
+ video->vgamem = virDomainVideoDefaultVgamem(video->type);
video->vram = virDomainVideoDefaultRAM(def, video->type);
video->heads = 1;
if (VIR_ALLOC_N(def->videos, 1) < 0) {
@@ -13558,6 +13595,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"),
@@ -16532,6 +16576,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 32674e0..a63ec84 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1216,6 +1216,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;
@@ -2459,7 +2460,7 @@ virDomainFSDefPtr virDomainFSRemove(virDomainDefPtr def, size_t i);
int virDomainVideoDefaultType(const virDomainDef *def);
int virDomainVideoDefaultRAM(const virDomainDef *def, int type);
-
+int virDomainVideoDefaultVgamem(int type);
int virDomainObjListNumOfDomains(virDomainObjListPtr doms,
bool active,
virDomainObjListFilter filter,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e59ea4c..18d5c17 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -434,6 +434,7 @@ virDomainVcpuPinDel;
virDomainVcpuPinFindByVcpu;
virDomainVcpuPinIsDuplicate;
virDomainVideoDefaultRAM;
+virDomainVideoDefaultVgamem;
virDomainVideoDefaultType;
virDomainVideoDefFree;
virDomainVideoTypeFromString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2185ef4..cb6d6e2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4812,6 +4812,13 @@ qemuBuildDeviceVideoStr(virDomainDefPtr def,
virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
}
+ /* 1. Ignore cirrus-vga as guests would not use it anyway.
+ * 2. QEMU accepts MByte for vgamem_mb and ensure its value
+ * a power of two and range: 1 MB -> 256 MB */
+ if (video->type != VIR_DOMAIN_VIDEO_TYPE_CIRRUS) {
+ virBufferAsprintf(&buf, ",vgamem_mb=%u", video->vgamem / 1024);
+ }
+
if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
goto error;
@@ -8499,36 +8506,55 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArgList(cmd, "-vga", vgastr, NULL);
- if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL &&
- (def->videos[0]->vram || def->videos[0]->ram) &&
- virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
- const char *dev = (virQEMUCapsGet(qemuCaps,
QEMU_CAPS_DEVICE_QXL_VGA)
- ? "qxl-vga" : "qxl");
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
+ const char *dev = NULL;
int ram = def->videos[0]->ram;
int vram = def->videos[0]->vram;
+ switch (primaryVideoType) {
+ case VIR_DOMAIN_VIDEO_TYPE_VGA:
+ dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA)
+ ? "VGA" : NULL);
+ break;
+ case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
+ dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA)
+ ? "vmware-svga" : NULL);
+ break;
+ case VIR_DOMAIN_VIDEO_TYPE_QXL:
+ dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)
+ ? "qxl-vga" : "qxl");
+ if (vram > (UINT_MAX / 1024)) {
+ virReportError(VIR_ERR_OVERFLOW,
+ _("value for 'vram' must be less than
'%u'"),
+ UINT_MAX / 1024);
+ goto error;
+ }
+ if (ram > (UINT_MAX / 1024)) {
+ virReportError(VIR_ERR_OVERFLOW,
+ _("value for 'ram' must be less than
'%u'"),
+ UINT_MAX / 1024);
+ goto error;
+ }
- if (vram > (UINT_MAX / 1024)) {
- virReportError(VIR_ERR_OVERFLOW,
- _("value for 'vram' must be less than
'%u'"),
- UINT_MAX / 1024);
- goto error;
- }
- if (ram > (UINT_MAX / 1024)) {
- virReportError(VIR_ERR_OVERFLOW,
- _("value for 'ram' must be less than
'%u'"),
- UINT_MAX / 1024);
- goto error;
- }
+ if (ram) {
+ virCommandAddArg(cmd, "-global");
+ virCommandAddArgFormat(cmd, "%s.ram_size=%u",
+ dev, ram * 1024);
+ }
+ if (vram) {
+ virCommandAddArg(cmd, "-global");
+ virCommandAddArgFormat(cmd, "%s.vram_size=%u",
+ dev, vram * 1024);
+ }
- if (ram) {
- virCommandAddArg(cmd, "-global");
- virCommandAddArgFormat(cmd, "%s.ram_size=%u",
- dev, ram * 1024);
+ break;
}
- if (vram) {
+
+ if (dev) {
+ /* QEMU accepts MByte for vgamem_mb and ensure its value
+ * a power of two and range: 1 MB -> 256 MB */
virCommandAddArg(cmd, "-global");
- virCommandAddArgFormat(cmd, "%s.vram_size=%u",
- dev, vram * 1024);
+ virCommandAddArgFormat(cmd, "%s.vgamem_mb=%u",
+ dev, def->videos[0]->vgamem /
1024);
}
}
}
@@ -11497,6 +11523,7 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
vid->type = VIR_DOMAIN_VIDEO_TYPE_XEN;
else
vid->type = video;
+ vid->vgamem = virDomainVideoDefaultVgamem(vid->type);
vid->vram = virDomainVideoDefaultRAM(def, vid->type);
vid->ram = vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL ?
virDomainVideoDefaultRAM(def, vid->type) : 0;
--
1.7.12.4