[libvirt] [PATCH RFC 1/3] qemu: Introduce vgamem attribute for video model

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@huawei.com> Signed-off-by: Wang Rui <moon.wangrui@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
participants (1)
-
Wangrui (K)