From: Zeng Junliang <zengjunliang@xxxxxxxxxx> 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@xxxxxxxxxx> Signed-off-by: Wang Rui <moon.wangrui@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list