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>
---
For KVM, vram attribute seems to be invalid for cirrus/vga/vmvga
device. Should we replace vram with vgamem? Or any other plans
for this vram attribute?
src/conf/domain_conf.c | 44 ++++++++++++++++++++++++++-
src/conf/domain_conf.h | 3 +-
src/libvirt_private.syms | 1 +
src/qemu/qemu_command.c | 79 +++++++++++++++++++++++++++++++++---------------
4 files changed, 100 insertions(+), 27 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ff2d447..58f6ed6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9358,6 +9358,24 @@ virDomainVideoDefaultRAM(const virDomainDef *def,
}
}
+int
+virDomainVideoDefaultVgamem(int type)
+{
+ switch (type) {
+ case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
+ /* QEMU use 8M as default value for cirrus device */
+ return 8 * 1024;
+
+ 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)
@@ -9443,6 +9461,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
char *type = NULL;
char *heads = NULL;
char *vram = NULL;
+ char *vgamem = NULL;
char *ram = NULL;
char *primary = NULL;
@@ -9452,11 +9471,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) {
@@ -9510,6 +9530,16 @@ virDomainVideoDefParseXML(xmlNodePtr node,
def->vram = virDomainVideoDefaultRAM(dom, def->type);
}
+ if (vgamem) {
+ 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,
@@ -9526,6 +9556,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
VIR_FREE(type);
VIR_FREE(ram);
VIR_FREE(vram);
+ VIR_FREE(vgamem);
VIR_FREE(heads);
return def;
@@ -9535,6 +9566,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
VIR_FREE(type);
VIR_FREE(ram);
VIR_FREE(vram);
+ VIR_FREE(vgamem);
VIR_FREE(heads);
return NULL;
}
@@ -12658,6 +12690,7 @@ virDomainDefParseXML(xmlDocPtr xml,
goto error;
}
video->vram = virDomainVideoDefaultRAM(def, video->type);
+ video->vgamem = virDomainVideoDefaultVgamem(video->type);
video->heads = 1;
if (VIR_ALLOC_N(def->videos, 1) < 0) {
virDomainVideoDefFree(video);
@@ -13578,6 +13611,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 +16572,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 a6ac95a..a72eeec 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;
@@ -2456,7 +2457,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 122c572..d8beed5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -421,6 +421,7 @@ virDomainVcpuPinDel;
virDomainVcpuPinFindByVcpu;
virDomainVcpuPinIsDuplicate;
virDomainVideoDefaultRAM;
+virDomainVideoDefaultVgamem;
virDomainVideoDefaultType;
virDomainVideoDefFree;
virDomainVideoTypeFromString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2caee66..2442ebd 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4931,6 +4931,11 @@ qemuBuildDeviceVideoStr(virDomainDefPtr def,
virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
}
+ /* QEMU accepts MByte for vgamem_mb and ensure its value
+ * a power of two and range: 1 MB -> 256 MB */
+ virBufferAsprintf(&buf, ",vgamem_mb=%u", video->vgamem / 1024);
+
+
if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
goto error;
@@ -8659,36 +8664,59 @@ 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");
- int ram = def->videos[0]->ram;
+ 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_CIRRUS:
+ dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA)
+ ? "cirrus-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);
}
}
}
@@ -11640,6 +11668,7 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
else
vid->type = video;
vid->vram = virDomainVideoDefaultRAM(def, vid->type);
+ vid->vgamem = virDomainVideoDefaultVgamem(vid->type);
vid->ram = vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL ?
virDomainVideoDefaultRAM(def, vid->type) : 0;
vid->heads = 1;
--
1.7.12.4