[libvirt PATCH v2 0/6] Add support for 'blob' to virtio video device

Add support to libvirt for the 'blob' option for virtio video devices in qemu. Also do a little preparatory refactoring of the video device xml parsing code. Changes in v2: - Added some basic documentation - add a qemu capability - Make sure that the /dev/udmabuf device is accessible to qemu (cgroups, etc) Jonathon Jongsma (6): conf: Refactor video model parsing conf: switch to virXMLProp* functions conf: use enum variable for video type conf: add support for 'blob' in virtio video device qemu: Add capability for virtio-gpu.blob qemu: Implement 'blob' support for virtio gpu docs/formatdomain.rst | 6 + docs/schemas/domaincommon.rng | 5 + src/conf/domain_conf.c | 133 +++++++++--------- src/conf/domain_conf.h | 3 +- src/conf/domain_validate.c | 13 +- src/libxl/libxl_conf.c | 10 ++ src/libxl/libxl_domain.c | 11 ++ src/qemu/qemu_capabilities.c | 4 + src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_cgroup.c | 28 ++-- src/qemu/qemu_command.c | 3 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_monitor_json.c | 16 ++- src/qemu/qemu_namespace.c | 22 +++ src/qemu/qemu_process.c | 7 + src/qemu/qemu_validate.c | 9 ++ .../caps_6.1.0.x86_64.xml | 1 + .../caps_6.2.0.aarch64.xml | 1 + .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml | 1 + .../caps_6.2.0.x86_64.xml | 1 + .../qemucapabilitiesdata/caps_7.0.0.ppc64.xml | 1 + .../caps_7.0.0.x86_64.xml | 1 + .../video-virtio-blob-absent.args | 34 +++++ .../video-virtio-blob-absent.xml | 33 +++++ .../video-virtio-blob-off.args | 34 +++++ .../video-virtio-blob-off.xml | 33 +++++ .../video-virtio-blob-on.args | 34 +++++ .../qemuxml2argvdata/video-virtio-blob-on.xml | 33 +++++ .../video-virtio-vga-blob-on.args | 34 +++++ .../video-virtio-vga-blob-on.xml | 33 +++++ tests/qemuxml2argvtest.c | 12 ++ .../video-virtio-blob-absent.xml | 41 ++++++ .../video-virtio-blob-off.xml | 41 ++++++ .../video-virtio-blob-on.xml | 41 ++++++ .../video-virtio-vga-blob-on.xml | 41 ++++++ tests/qemuxml2xmltest.c | 12 ++ 36 files changed, 652 insertions(+), 84 deletions(-) create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-absent.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-absent.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-off.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-off.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-on.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-on.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-vga-blob-on.args create mode 100644 tests/qemuxml2argvdata/video-virtio-vga-blob-on.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-absent.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-off.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-on.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-vga-blob-on.xml -- 2.35.1

Factor out a separate function to parse out the <model> element for video devices. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/conf/domain_conf.c | 95 ++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 34fec887a3..1d0698d9fe 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14067,17 +14067,13 @@ virDomainVideoDriverDefParseXML(xmlNodePtr node, return g_steal_pointer(&def); } -static virDomainVideoDef * -virDomainVideoDefParseXML(virDomainXMLOption *xmlopt, - xmlNodePtr node, - xmlXPathContextPtr ctxt, - unsigned int flags) +static int +virDomainVideoModelDefParseXML(virDomainVideoDef *def, + xmlNodePtr node, + xmlXPathContextPtr ctxt) { - g_autoptr(virDomainVideoDef) def = NULL; - xmlNodePtr driver; xmlNodePtr accel_node; xmlNodePtr res_node; - VIR_XPATH_NODE_AUTORESTORE(ctxt) g_autofree char *type = NULL; g_autofree char *heads = NULL; g_autofree char *vram = NULL; @@ -14086,81 +14082,108 @@ virDomainVideoDefParseXML(virDomainXMLOption *xmlopt, g_autofree char *vgamem = NULL; g_autofree char *primary = NULL; - if (!(def = virDomainVideoDefNew(xmlopt))) - return NULL; - + VIR_XPATH_NODE_AUTORESTORE(ctxt); ctxt->node = node; - if ((primary = virXPathString("string(./model/@primary)", ctxt)) != NULL) + if ((primary = virXPathString("string(./@primary)", ctxt)) != NULL) ignore_value(virStringParseYesNo(primary, &def->primary)); - if ((accel_node = virXPathNode("./model/acceleration", ctxt)) && + if ((accel_node = virXPathNode("./acceleration", ctxt)) && (def->accel = virDomainVideoAccelDefParseXML(accel_node)) == NULL) - return NULL; + return -1; - if ((res_node = virXPathNode("./model/resolution", ctxt)) && + if ((res_node = virXPathNode("./resolution", ctxt)) && (def->res = virDomainVideoResolutionDefParseXML(res_node)) == NULL) - return NULL; + return -1; - if ((driver = virXPathNode("./driver", ctxt))) { - if (virXMLPropEnum(driver, "name", - virDomainVideoBackendTypeFromString, - VIR_XML_PROP_NONZERO, &def->backend) < 0) - return NULL; - if (virDomainVirtioOptionsParseXML(driver, &def->virtio) < 0) - return NULL; - } - if ((type = virXPathString("string(./model/@type)", ctxt))) { + + if ((type = virXPathString("string(./@type)", ctxt))) { if ((def->type = virDomainVideoTypeFromString(type)) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unknown video model '%s'"), type); - return NULL; + return -1; } } else { def->type = VIR_DOMAIN_VIDEO_TYPE_DEFAULT; } - if ((ram = virXPathString("string(./model/@ram)", ctxt))) { + if ((ram = virXPathString("string(./@ram)", ctxt))) { if (virStrToLong_uip(ram, NULL, 10, &def->ram) < 0) { virReportError(VIR_ERR_XML_ERROR, _("cannot parse video ram '%s'"), ram); - return NULL; + return -1; } } - if ((vram = virXPathString("string(./model/@vram)", ctxt))) { + if ((vram = virXPathString("string(./@vram)", ctxt))) { if (virStrToLong_uip(vram, NULL, 10, &def->vram) < 0) { virReportError(VIR_ERR_XML_ERROR, _("cannot parse video vram '%s'"), vram); - return NULL; + return -1; } } - if ((vram64 = virXPathString("string(./model/@vram64)", ctxt))) { + if ((vram64 = virXPathString("string(./@vram64)", ctxt))) { if (virStrToLong_uip(vram64, NULL, 10, &def->vram64) < 0) { virReportError(VIR_ERR_XML_ERROR, _("cannot parse video vram64 '%s'"), vram64); - return NULL; + return -1; } } - if ((vgamem = virXPathString("string(./model/@vgamem)", ctxt))) { + if ((vgamem = virXPathString("string(./@vgamem)", ctxt))) { if (virStrToLong_uip(vgamem, NULL, 10, &def->vgamem) < 0) { virReportError(VIR_ERR_XML_ERROR, _("cannot parse video vgamem '%s'"), vgamem); - return NULL; + return -1; } } - if ((heads = virXPathString("string(./model/@heads)", ctxt))) { + if ((heads = virXPathString("string(./@heads)", ctxt))) { if (virStrToLong_uip(heads, NULL, 10, &def->heads) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot parse video heads '%s'"), heads); - return NULL; + return -1; } } + return 0; +} + +static virDomainVideoDef * +virDomainVideoDefParseXML(virDomainXMLOption *xmlopt, + xmlNodePtr node, + xmlXPathContextPtr ctxt, + unsigned int flags) +{ + g_autoptr(virDomainVideoDef) def = NULL; + xmlNodePtr driver; + xmlNodePtr model; + + VIR_XPATH_NODE_AUTORESTORE(ctxt) + + if (!(def = virDomainVideoDefNew(xmlopt))) + return NULL; + + ctxt->node = node; + + if ((model = virXPathNode("./model", ctxt))) { + if (virDomainVideoModelDefParseXML(def, model, ctxt) < 0) + return NULL; + } else { + def->type = VIR_DOMAIN_VIDEO_TYPE_DEFAULT; + } + + if ((driver = virXPathNode("./driver", ctxt))) { + if (virXMLPropEnum(driver, "name", + virDomainVideoBackendTypeFromString, + VIR_XML_PROP_NONZERO, &def->backend) < 0) + return NULL; + if (virDomainVirtioOptionsParseXML(driver, &def->virtio) < 0) + return NULL; + } + if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &def->info, flags) < 0) return NULL; -- 2.35.1

In virDomainVideoModelDefParseXML(), use the virXMLProp* functions rather than reimplementing them with virXPath* functions. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/conf/domain_conf.c | 78 +++++++++++++----------------------------- 1 file changed, 23 insertions(+), 55 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1d0698d9fe..3a97358a11 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14074,19 +14074,15 @@ virDomainVideoModelDefParseXML(virDomainVideoDef *def, { xmlNodePtr accel_node; xmlNodePtr res_node; - g_autofree char *type = NULL; - g_autofree char *heads = NULL; - g_autofree char *vram = NULL; - g_autofree char *vram64 = NULL; - g_autofree char *ram = NULL; - g_autofree char *vgamem = NULL; - g_autofree char *primary = NULL; + virDomainVideoType type; + virTristateBool primary; + int rc = 0; VIR_XPATH_NODE_AUTORESTORE(ctxt); ctxt->node = node; - if ((primary = virXPathString("string(./@primary)", ctxt)) != NULL) - ignore_value(virStringParseYesNo(primary, &def->primary)); + if (virXMLPropTristateBool(node, "primary", VIR_XML_PROP_NONE, &primary) >= 0) + def->primary = (primary == VIR_TRISTATE_BOOL_YES); if ((accel_node = virXPathNode("./acceleration", ctxt)) && (def->accel = virDomainVideoAccelDefParseXML(accel_node)) == NULL) @@ -14096,57 +14092,29 @@ virDomainVideoModelDefParseXML(virDomainVideoDef *def, (def->res = virDomainVideoResolutionDefParseXML(res_node)) == NULL) return -1; + if (virXMLPropEnumDefault(node, "type", + virDomainVideoTypeFromString, + VIR_XML_PROP_NONE, &type, + VIR_DOMAIN_VIDEO_TYPE_DEFAULT) < 0) + return -1; + def->type = type; + if (virXMLPropUInt(node, "ram", 10, VIR_XML_PROP_NONE, &def->ram) < 0) + return -1; - if ((type = virXPathString("string(./@type)", ctxt))) { - if ((def->type = virDomainVideoTypeFromString(type)) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown video model '%s'"), type); - return -1; - } - } else { - def->type = VIR_DOMAIN_VIDEO_TYPE_DEFAULT; - } - - if ((ram = virXPathString("string(./@ram)", ctxt))) { - if (virStrToLong_uip(ram, NULL, 10, &def->ram) < 0) { - virReportError(VIR_ERR_XML_ERROR, - _("cannot parse video ram '%s'"), ram); - return -1; - } - } - - if ((vram = virXPathString("string(./@vram)", ctxt))) { - if (virStrToLong_uip(vram, NULL, 10, &def->vram) < 0) { - virReportError(VIR_ERR_XML_ERROR, - _("cannot parse video vram '%s'"), vram); - return -1; - } - } + if (virXMLPropUInt(node, "vram", 10, VIR_XML_PROP_NONE, &def->vram) < 0) + return -1; - if ((vram64 = virXPathString("string(./@vram64)", ctxt))) { - if (virStrToLong_uip(vram64, NULL, 10, &def->vram64) < 0) { - virReportError(VIR_ERR_XML_ERROR, - _("cannot parse video vram64 '%s'"), vram64); - return -1; - } - } + if (virXMLPropUInt(node, "vram64", 10, VIR_XML_PROP_NONE, &def->vram64) < 0) + return -1; - if ((vgamem = virXPathString("string(./@vgamem)", ctxt))) { - if (virStrToLong_uip(vgamem, NULL, 10, &def->vgamem) < 0) { - virReportError(VIR_ERR_XML_ERROR, - _("cannot parse video vgamem '%s'"), vgamem); - return -1; - } - } + if (virXMLPropUInt(node, "vgamem", 10, VIR_XML_PROP_NONE, &def->vgamem) < 0) + return -1; - if ((heads = virXPathString("string(./@heads)", ctxt))) { - if (virStrToLong_uip(heads, NULL, 10, &def->heads) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot parse video heads '%s'"), heads); - return -1; - } - } + if ((rc = virXMLPropUInt(node, "heads", 10, VIR_XML_PROP_NONE, &def->heads)) < 0) + return -1; + else if (rc == 0) + def->heads = 1; return 0; } -- 2.35.1

Rather than storing the video type as an integer, use the proper enum type within the struct. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/conf/domain_conf.c | 4 +--- src/conf/domain_conf.h | 2 +- src/libxl/libxl_conf.c | 10 ++++++++++ src/libxl/libxl_domain.c | 11 +++++++++++ src/qemu/qemu_monitor_json.c | 16 +++++++++++++++- src/qemu/qemu_process.c | 7 +++++++ 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3a97358a11..39aa6a1058 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14074,7 +14074,6 @@ virDomainVideoModelDefParseXML(virDomainVideoDef *def, { xmlNodePtr accel_node; xmlNodePtr res_node; - virDomainVideoType type; virTristateBool primary; int rc = 0; @@ -14094,10 +14093,9 @@ virDomainVideoModelDefParseXML(virDomainVideoDef *def, if (virXMLPropEnumDefault(node, "type", virDomainVideoTypeFromString, - VIR_XML_PROP_NONE, &type, + VIR_XML_PROP_NONE, &def->type, VIR_DOMAIN_VIDEO_TYPE_DEFAULT) < 0) return -1; - def->type = type; if (virXMLPropUInt(node, "ram", 10, VIR_XML_PROP_NONE, &def->ram) < 0) return -1; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9fcf842ee7..fa64491978 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1727,7 +1727,7 @@ struct _virDomainVideoDriverDef { struct _virDomainVideoDef { virObject *privateData; - int type; /* enum virDomainVideoType */ + virDomainVideoType type; unsigned int ram; /* kibibytes (multiples of 1024) */ unsigned int vram; /* kibibytes (multiples of 1024) */ unsigned int vram64; /* kibibytes (multiples of 1024) */ diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index a0fc51c74a..1a608960b1 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -2364,6 +2364,16 @@ libxlMakeVideo(virDomainDef *def, libxl_domain_config *d_config) } break; + case VIR_DOMAIN_VIDEO_TYPE_DEFAULT: + case VIR_DOMAIN_VIDEO_TYPE_VMVGA: + case VIR_DOMAIN_VIDEO_TYPE_VBOX: + case VIR_DOMAIN_VIDEO_TYPE_PARALLELS: + case VIR_DOMAIN_VIDEO_TYPE_VIRTIO: + case VIR_DOMAIN_VIDEO_TYPE_GOP: + case VIR_DOMAIN_VIDEO_TYPE_NONE: + case VIR_DOMAIN_VIDEO_TYPE_BOCHS: + case VIR_DOMAIN_VIDEO_TYPE_RAMFB: + case VIR_DOMAIN_VIDEO_TYPE_LAST: default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("video type %s is not supported by libxl"), diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index ee031267ca..d4ba030c2a 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -331,6 +331,17 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDef *dev, if (dev->data.video->vram == 0) dev->data.video->vram = 128 * 1024; break; + case VIR_DOMAIN_VIDEO_TYPE_DEFAULT: + case VIR_DOMAIN_VIDEO_TYPE_VMVGA: + case VIR_DOMAIN_VIDEO_TYPE_VBOX: + case VIR_DOMAIN_VIDEO_TYPE_PARALLELS: + case VIR_DOMAIN_VIDEO_TYPE_VIRTIO: + case VIR_DOMAIN_VIDEO_TYPE_GOP: + case VIR_DOMAIN_VIDEO_TYPE_NONE: + case VIR_DOMAIN_VIDEO_TYPE_BOCHS: + case VIR_DOMAIN_VIDEO_TYPE_RAMFB: + case VIR_DOMAIN_VIDEO_TYPE_LAST: + break; } } } diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 4d339f29b8..791463e2bb 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1897,9 +1897,16 @@ qemuMonitorJSONUpdateVideoMemorySize(qemuMonitor *mon, } video->vram = prop.val.ul * 1024; break; + case VIR_DOMAIN_VIDEO_TYPE_DEFAULT: case VIR_DOMAIN_VIDEO_TYPE_CIRRUS: case VIR_DOMAIN_VIDEO_TYPE_XEN: case VIR_DOMAIN_VIDEO_TYPE_VBOX: + case VIR_DOMAIN_VIDEO_TYPE_PARALLELS: + case VIR_DOMAIN_VIDEO_TYPE_VIRTIO: + case VIR_DOMAIN_VIDEO_TYPE_GOP: + case VIR_DOMAIN_VIDEO_TYPE_NONE: + case VIR_DOMAIN_VIDEO_TYPE_BOCHS: + case VIR_DOMAIN_VIDEO_TYPE_RAMFB: case VIR_DOMAIN_VIDEO_TYPE_LAST: break; } @@ -1937,11 +1944,18 @@ qemuMonitorJSONUpdateVideoVram64Size(qemuMonitor *mon, video->vram64 = prop.val.ul * 1024; } break; + case VIR_DOMAIN_VIDEO_TYPE_DEFAULT: case VIR_DOMAIN_VIDEO_TYPE_VGA: - case VIR_DOMAIN_VIDEO_TYPE_VMVGA: case VIR_DOMAIN_VIDEO_TYPE_CIRRUS: + case VIR_DOMAIN_VIDEO_TYPE_VMVGA: case VIR_DOMAIN_VIDEO_TYPE_XEN: case VIR_DOMAIN_VIDEO_TYPE_VBOX: + case VIR_DOMAIN_VIDEO_TYPE_PARALLELS: + case VIR_DOMAIN_VIDEO_TYPE_VIRTIO: + case VIR_DOMAIN_VIDEO_TYPE_GOP: + case VIR_DOMAIN_VIDEO_TYPE_NONE: + case VIR_DOMAIN_VIDEO_TYPE_BOCHS: + case VIR_DOMAIN_VIDEO_TYPE_RAMFB: case VIR_DOMAIN_VIDEO_TYPE_LAST: break; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 5af925e521..bdb213b7c8 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3097,9 +3097,16 @@ qemuProcessUpdateVideoRamSize(virQEMUDriver *driver, goto error; } break; + case VIR_DOMAIN_VIDEO_TYPE_DEFAULT: case VIR_DOMAIN_VIDEO_TYPE_CIRRUS: case VIR_DOMAIN_VIDEO_TYPE_XEN: case VIR_DOMAIN_VIDEO_TYPE_VBOX: + case VIR_DOMAIN_VIDEO_TYPE_PARALLELS: + case VIR_DOMAIN_VIDEO_TYPE_VIRTIO: + case VIR_DOMAIN_VIDEO_TYPE_GOP: + case VIR_DOMAIN_VIDEO_TYPE_NONE: + case VIR_DOMAIN_VIDEO_TYPE_BOCHS: + case VIR_DOMAIN_VIDEO_TYPE_RAMFB: case VIR_DOMAIN_VIDEO_TYPE_LAST: break; } -- 2.35.1

Add the ability to enable blob resources for the virtio video device. This will accelerate the display path due to less or no copying of pixel data. Blob resource support can be enabled with e.g.: <video> <model type='virtio' blob='on'/> </video> Some additional background information about blob resources: https://lists.freedesktop.org/archives/dri-devel/2020-August/275972.html https://www.kraxel.org/blog/2021/05/virtio-gpu-qemu-graphics-update/ Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2032406 Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- docs/formatdomain.rst | 6 ++++++ docs/schemas/domaincommon.rng | 5 +++++ src/conf/domain_conf.c | 6 ++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 13 ++++++++++--- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 9202cd3107..62edcea7a7 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -6239,6 +6239,12 @@ A video device. :since:`since 1.3.3` ) extends secondary bar and makes it addressable as 64bit memory. + :since:`Since 8.1.0`, devices with type "virtio" have an optional ``blob`` + attribute that can be set to "on" or "off". Setting ``blob`` to "on" will + enable the use of blob resources in the device. This can accelerate the + display path by reducing or eliminating copying of pixel data between the + guest and host. + :since:`Since 5.9.0` , the ``model`` element may also have an optional ``resolution`` sub-element. The ``resolution`` element has attributes ``x`` and ``y`` to set the minimum resolution for the video device. This diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 964b0c9e2f..372376820a 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4191,6 +4191,11 @@ <ref name="virYesNo"/> </attribute> </optional> + <optional> + <attribute name="blob"> + <ref name="virOnOff"/> + </attribute> + </optional> <optional> <element name="acceleration"> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 39aa6a1058..6ea5e62655 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14114,6 +14114,9 @@ virDomainVideoModelDefParseXML(virDomainVideoDef *def, else if (rc == 0) def->heads = 1; + if (virXMLPropTristateSwitch(node, "blob", VIR_XML_PROP_NONE, &def->blob) < 0) + return -1; + return 0; } @@ -26000,6 +26003,9 @@ virDomainVideoDefFormat(virBuffer *buf, virBufferAsprintf(buf, " heads='%u'", def->heads); if (def->primary) virBufferAddLit(buf, " primary='yes'"); + if (def->blob != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(buf, " blob='%s'", + virTristateSwitchTypeToString(def->blob)); if (def->accel || def->res) { virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index fa64491978..e66f8381e5 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1736,6 +1736,7 @@ struct _virDomainVideoDef { bool primary; virDomainVideoAccelDef *accel; virDomainVideoResolutionDef *res; + virTristateSwitch blob; virDomainVideoDriverDef *driver; virDomainDeviceInfo info; virDomainVirtioOptions *virtio; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index f0b8aa2655..c5c6f7df15 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -226,9 +226,16 @@ virDomainVideoDefValidate(const virDomainVideoDef *video, } } - if (video->type != VIR_DOMAIN_VIDEO_TYPE_VIRTIO && - (virDomainCheckVirtioOptionsAreAbsent(video->virtio) < 0)) - return -1; + if (video->type != VIR_DOMAIN_VIDEO_TYPE_VIRTIO) { + if (virDomainCheckVirtioOptionsAreAbsent(video->virtio) < 0) + return -1; + if (video->blob != VIR_TRISTATE_SWITCH_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("video type '%s' does not support blob resources"), + virDomainVideoTypeToString(video->type)); + return -1; + } + } return 0; } -- 2.35.1

Capability to determine whether this qemu supports the 'blob' option for virtio-gpu. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml | 1 + 8 files changed, 13 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 529e9ceaf5..0b52967c75 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -665,6 +665,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-mem-pci.prealloc", /* QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_PREALLOC */ "calc-dirty-rate", /* QEMU_CAPS_CALC_DIRTY_RATE */ "dirtyrate-param.mode", /* QEMU_CAPS_DIRTYRATE_MODE */ + + /* 425 */ + "virtio-gpu.blob", /* QEMU_CAPS_VIRTIO_GPU_BLOB */ ); @@ -1546,6 +1549,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVirtioGpu[] = { { "disable-legacy", QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, NULL }, { "packed", QEMU_CAPS_VIRTIO_PACKED_QUEUES, NULL }, { "acpi-index", QEMU_CAPS_ACPI_INDEX, NULL }, + { "blob", QEMU_CAPS_VIRTIO_GPU_BLOB, NULL }, }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsICH9[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f6188b42de..ff8e599ea7 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -641,6 +641,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_CALC_DIRTY_RATE, /* accepts calc-dirty-rate */ QEMU_CAPS_DIRTYRATE_MODE , /* calc-dirty-rate accepts mode parameter */ + /* 425 */ + QEMU_CAPS_VIRTIO_GPU_BLOB, /* -device virtio-gpu-*.blob= */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml index ba1aecc37e..49071b1ef1 100644 --- a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml @@ -239,6 +239,7 @@ <flag name='rbd-encryption'/> <flag name='sev-inject-launch-secret'/> <flag name='calc-dirty-rate'/> + <flag name='virtio-gpu.blob'/> <version>6001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml index 17d563eb5b..487f38f5d7 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml @@ -203,6 +203,7 @@ <flag name='query-dirty-rate'/> <flag name='rbd-encryption'/> <flag name='calc-dirty-rate'/> + <flag name='virtio-gpu.blob'/> <version>6001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml index 9fe9c27d14..e3f31d1809 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml @@ -201,6 +201,7 @@ <flag name='sev-guest-kernel-hashes'/> <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> + <flag name='virtio-gpu.blob'/> <version>6002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml index d77907af55..6a0b969113 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml @@ -241,6 +241,7 @@ <flag name='sev-inject-launch-secret'/> <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> + <flag name='virtio-gpu.blob'/> <version>6002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml index 5d7f283a73..0780f95f6f 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml @@ -202,6 +202,7 @@ <flag name='device.json+hotplug'/> <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> + <flag name='virtio-gpu.blob'/> <version>6002050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml index ae800abcc4..7e882dee40 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml @@ -243,6 +243,7 @@ <flag name='virtio-mem-pci.prealloc'/> <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> + <flag name='virtio-gpu.blob'/> <version>6002050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion> -- 2.35.1

This can improve performance for some guests since it reduces copying of display data between host and guest. Requires udmabuf on the host. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/qemu/qemu_cgroup.c | 28 ++++++++----- src/qemu/qemu_command.c | 3 ++ src/qemu/qemu_domain.h | 1 + src/qemu/qemu_namespace.c | 22 ++++++++++ src/qemu/qemu_validate.c | 9 ++++ .../video-virtio-blob-absent.args | 34 +++++++++++++++ .../video-virtio-blob-absent.xml | 33 +++++++++++++++ .../video-virtio-blob-off.args | 34 +++++++++++++++ .../video-virtio-blob-off.xml | 33 +++++++++++++++ .../video-virtio-blob-on.args | 34 +++++++++++++++ .../qemuxml2argvdata/video-virtio-blob-on.xml | 33 +++++++++++++++ .../video-virtio-vga-blob-on.args | 34 +++++++++++++++ .../video-virtio-vga-blob-on.xml | 33 +++++++++++++++ tests/qemuxml2argvtest.c | 12 ++++++ .../video-virtio-blob-absent.xml | 41 +++++++++++++++++++ .../video-virtio-blob-off.xml | 41 +++++++++++++++++++ .../video-virtio-blob-on.xml | 41 +++++++++++++++++++ .../video-virtio-vga-blob-on.xml | 41 +++++++++++++++++++ tests/qemuxml2xmltest.c | 12 ++++++ 19 files changed, 509 insertions(+), 10 deletions(-) create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-absent.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-absent.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-off.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-off.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-on.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-on.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-vga-blob-on.args create mode 100644 tests/qemuxml2argvdata/video-virtio-vga-blob-on.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-absent.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-off.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-on.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-vga-blob-on.xml diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 34b50ddd1d..e8f982b146 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -579,18 +579,26 @@ qemuSetupVideoCgroup(virDomainObj *vm, virDomainVideoAccelDef *accel = def->accel; int ret; - if (!accel) - return 0; - - if (!accel->rendernode || - !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) + if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) return 0; - ret = virCgroupAllowDevicePath(priv->cgroup, accel->rendernode, - VIR_CGROUP_DEVICE_RW, false); - virDomainAuditCgroupPath(vm, priv->cgroup, "allow", accel->rendernode, - "rw", ret); - return ret; + if (accel && accel->rendernode) { + ret = virCgroupAllowDevicePath(priv->cgroup, accel->rendernode, + VIR_CGROUP_DEVICE_RW, false); + virDomainAuditCgroupPath(vm, priv->cgroup, "allow", accel->rendernode, + "rw", ret); + if (ret != 0) + return ret; + } + if (def->blob == VIR_TRISTATE_SWITCH_ON) { + ret = virCgroupAllowDevicePath(priv->cgroup, QEMU_DEV_UDMABUF, + VIR_CGROUP_DEVICE_RW, false); + virDomainAuditCgroupPath(vm, priv->cgroup, "allow", QEMU_DEV_UDMABUF, + "rw", ret); + if (ret != 0) + return ret; + } + return 0; } static int diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index c836799888..b64c9e3b12 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4854,6 +4854,9 @@ qemuBuildDeviceVideoCmd(virCommand *cmd, "p:vgamem", video->vram * 1024, NULL) < 0) return -1; + } else if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) { + if (virJSONValueObjectAdd(&props, "T:blob", video->blob, NULL) < 0) + return -1; } if (video->res) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index be56b5dbb3..8ff0dafaa0 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -89,6 +89,7 @@ struct _qemuDomainUnpluggingDevice { #define QEMU_DEV_VFIO "/dev/vfio/vfio" #define QEMU_DEV_SEV "/dev/sev" #define QEMU_DEVICE_MAPPER_CONTROL_PATH "/dev/mapper/control" +#define QEMU_DEV_UDMABUF "/dev/udmabuf" #define QEMU_DOMAIN_AES_IV_LEN 16 /* 16 bytes for 128 bit random */ diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c index 3b41d72630..0a1118ac33 100644 --- a/src/qemu/qemu_namespace.c +++ b/src/qemu/qemu_namespace.c @@ -485,6 +485,25 @@ qemuDomainSetupAllGraphics(virDomainObj *vm, } +static int +qemuDomainSetupAllVideos(virDomainObj *vm, + GSList **paths) +{ + size_t i; + + VIR_DEBUG("Setting up video devices"); + for (i = 0; i < vm->def->nvideos; i++) { + virDomainVideoDef *video = vm->def->videos[i]; + if (video->blob == VIR_TRISTATE_SWITCH_ON) { + *paths = g_slist_prepend(*paths, g_strdup(QEMU_DEV_UDMABUF)); + break; + } + } + + return 0; +} + + static int qemuDomainSetupInput(virDomainInputDef *input, GSList **paths) @@ -654,6 +673,9 @@ qemuDomainBuildNamespace(virQEMUDriverConfig *cfg, if (qemuDomainSetupAllGraphics(vm, &paths) < 0) return -1; + if (qemuDomainSetupAllVideos(vm, &paths) < 0) + return -1; + if (qemuDomainSetupAllInputs(vm, &paths) < 0) return -1; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index f27e480696..14ca81a080 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -2570,6 +2570,15 @@ qemuValidateDomainDeviceDefVideo(const virDomainVideoDef *video, } } + if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) { + if (video->blob != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_BLOB)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this QEMU does not support 'blob' for virtio-gpu devices")); + return -1; + } + } + if (qemuValidateDomainVirtioOptions(video->virtio, qemuCaps) < 0) return -1; diff --git a/tests/qemuxml2argvdata/video-virtio-blob-absent.args b/tests/qemuxml2argvdata/video-virtio-blob-absent.args new file mode 100644 index 0000000000..36a5b9bba8 --- /dev/null +++ b/tests/qemuxml2argvdata/video-virtio-blob-absent.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i386 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,usb=off,dump-guest-core=off \ +-accel tcg \ +-m 1024 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-usb \ +-drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,id=drive-ide0-0-0,cache=none \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-device virtio-gpu-pci,id=video0,max_outputs=1,bus=pci.0,addr=0x2 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/video-virtio-blob-absent.xml b/tests/qemuxml2argvdata/video-virtio-blob-absent.xml new file mode 100644 index 0000000000..a9354d77a2 --- /dev/null +++ b/tests/qemuxml2argvdata/video-virtio-blob-absent.xml @@ -0,0 +1,33 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>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-system-i386</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'/> + <controller type='usb' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <video> + <model type='virtio' heads='1'/> + </video> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/video-virtio-blob-off.args b/tests/qemuxml2argvdata/video-virtio-blob-off.args new file mode 100644 index 0000000000..eadae278ce --- /dev/null +++ b/tests/qemuxml2argvdata/video-virtio-blob-off.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i386 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,usb=off,dump-guest-core=off \ +-accel tcg \ +-m 1024 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-usb \ +-drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,id=drive-ide0-0-0,cache=none \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-device virtio-gpu-pci,id=video0,max_outputs=1,blob=off,bus=pci.0,addr=0x2 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/video-virtio-blob-off.xml b/tests/qemuxml2argvdata/video-virtio-blob-off.xml new file mode 100644 index 0000000000..7b51762e9a --- /dev/null +++ b/tests/qemuxml2argvdata/video-virtio-blob-off.xml @@ -0,0 +1,33 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>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-system-i386</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'/> + <controller type='usb' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <video> + <model type='virtio' heads='1' blob='off'/> + </video> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/video-virtio-blob-on.args b/tests/qemuxml2argvdata/video-virtio-blob-on.args new file mode 100644 index 0000000000..6fbb0d5bb2 --- /dev/null +++ b/tests/qemuxml2argvdata/video-virtio-blob-on.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i386 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,usb=off,dump-guest-core=off \ +-accel tcg \ +-m 1024 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-usb \ +-drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,id=drive-ide0-0-0,cache=none \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-device virtio-gpu-pci,id=video0,max_outputs=1,blob=on,bus=pci.0,addr=0x2 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/video-virtio-blob-on.xml b/tests/qemuxml2argvdata/video-virtio-blob-on.xml new file mode 100644 index 0000000000..187347fac0 --- /dev/null +++ b/tests/qemuxml2argvdata/video-virtio-blob-on.xml @@ -0,0 +1,33 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>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-system-i386</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'/> + <controller type='usb' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <video> + <model type='virtio' heads='1' blob="on"/> + </video> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/video-virtio-vga-blob-on.args b/tests/qemuxml2argvdata/video-virtio-vga-blob-on.args new file mode 100644 index 0000000000..8b7085e1a3 --- /dev/null +++ b/tests/qemuxml2argvdata/video-virtio-vga-blob-on.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i386 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,usb=off,dump-guest-core=off \ +-accel tcg \ +-m 1024 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-usb \ +-drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,id=drive-ide0-0-0,cache=none \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-device virtio-vga,id=video0,max_outputs=1,blob=on,bus=pci.0,addr=0x2 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/video-virtio-vga-blob-on.xml b/tests/qemuxml2argvdata/video-virtio-vga-blob-on.xml new file mode 100644 index 0000000000..00aed31d28 --- /dev/null +++ b/tests/qemuxml2argvdata/video-virtio-vga-blob-on.xml @@ -0,0 +1,33 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>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-system-i386</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'/> + <controller type='usb' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <video> + <model type='virtio' primary="yes" heads='1' blob="on"/> + </video> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ce475df466..991cfd6ab0 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2462,6 +2462,18 @@ mymain(void) DO_TEST("video-virtio-vga", QEMU_CAPS_DEVICE_VIRTIO_GPU, QEMU_CAPS_DEVICE_VIRTIO_VGA); + DO_TEST("video-virtio-blob-on", + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_VIRTIO_GPU_BLOB); + DO_TEST("video-virtio-vga-blob-on", + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_VGA, + QEMU_CAPS_VIRTIO_GPU_BLOB); + DO_TEST("video-virtio-blob-off", + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_VIRTIO_GPU_BLOB); + DO_TEST("video-virtio-blob-absent", + QEMU_CAPS_DEVICE_VIRTIO_GPU); DO_TEST_CAPS_LATEST("video-virtio-vga-gpu-gl"); DO_TEST_CAPS_LATEST("video-bochs-display-device"); DO_TEST_CAPS_LATEST("video-ramfb-display-device"); diff --git a/tests/qemuxml2xmloutdata/video-virtio-blob-absent.xml b/tests/qemuxml2xmloutdata/video-virtio-blob-absent.xml new file mode 100644 index 0000000000..827ed19153 --- /dev/null +++ b/tests/qemuxml2xmloutdata/video-virtio-blob-absent.xml @@ -0,0 +1,41 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>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-system-i386</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'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <video> + <model type='virtio' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/video-virtio-blob-off.xml b/tests/qemuxml2xmloutdata/video-virtio-blob-off.xml new file mode 100644 index 0000000000..5742687d6a --- /dev/null +++ b/tests/qemuxml2xmloutdata/video-virtio-blob-off.xml @@ -0,0 +1,41 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>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-system-i386</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'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <video> + <model type='virtio' heads='1' primary='yes' blob='off'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/video-virtio-blob-on.xml b/tests/qemuxml2xmloutdata/video-virtio-blob-on.xml new file mode 100644 index 0000000000..649c4e5e4c --- /dev/null +++ b/tests/qemuxml2xmloutdata/video-virtio-blob-on.xml @@ -0,0 +1,41 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>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-system-i386</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'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <video> + <model type='virtio' heads='1' primary='yes' blob='on'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/video-virtio-vga-blob-on.xml b/tests/qemuxml2xmloutdata/video-virtio-vga-blob-on.xml new file mode 100644 index 0000000000..649c4e5e4c --- /dev/null +++ b/tests/qemuxml2xmloutdata/video-virtio-vga-blob-on.xml @@ -0,0 +1,41 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>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-system-i386</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'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <video> + <model type='virtio' heads='1' primary='yes' blob='on'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 052950b86f..5fa7881a87 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1275,6 +1275,18 @@ mymain(void) QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW); DO_TEST("video-none-device", QEMU_CAPS_VNC); DO_TEST_CAPS_LATEST("video-virtio-vga-gpu-gl"); + DO_TEST("video-virtio-blob-on", + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_VIRTIO_GPU_BLOB); + DO_TEST("video-virtio-vga-blob-on", + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_VGA, + QEMU_CAPS_VIRTIO_GPU_BLOB); + DO_TEST("video-virtio-blob-off", + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_VIRTIO_GPU_BLOB); + DO_TEST("video-virtio-blob-absent", + QEMU_CAPS_DEVICE_VIRTIO_GPU); DO_TEST_CAPS_LATEST("intel-iommu"); DO_TEST_CAPS_LATEST("intel-iommu-caching-mode"); -- 2.35.1

ping On 2/24/22 2:47 PM, Jonathon Jongsma wrote:
Add support to libvirt for the 'blob' option for virtio video devices in qemu. Also do a little preparatory refactoring of the video device xml parsing code.
Changes in v2: - Added some basic documentation - add a qemu capability - Make sure that the /dev/udmabuf device is accessible to qemu (cgroups, etc)
Jonathon Jongsma (6): conf: Refactor video model parsing conf: switch to virXMLProp* functions conf: use enum variable for video type conf: add support for 'blob' in virtio video device qemu: Add capability for virtio-gpu.blob qemu: Implement 'blob' support for virtio gpu
docs/formatdomain.rst | 6 + docs/schemas/domaincommon.rng | 5 + src/conf/domain_conf.c | 133 +++++++++--------- src/conf/domain_conf.h | 3 +- src/conf/domain_validate.c | 13 +- src/libxl/libxl_conf.c | 10 ++ src/libxl/libxl_domain.c | 11 ++ src/qemu/qemu_capabilities.c | 4 + src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_cgroup.c | 28 ++-- src/qemu/qemu_command.c | 3 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_monitor_json.c | 16 ++- src/qemu/qemu_namespace.c | 22 +++ src/qemu/qemu_process.c | 7 + src/qemu/qemu_validate.c | 9 ++ .../caps_6.1.0.x86_64.xml | 1 + .../caps_6.2.0.aarch64.xml | 1 + .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml | 1 + .../caps_6.2.0.x86_64.xml | 1 + .../qemucapabilitiesdata/caps_7.0.0.ppc64.xml | 1 + .../caps_7.0.0.x86_64.xml | 1 + .../video-virtio-blob-absent.args | 34 +++++ .../video-virtio-blob-absent.xml | 33 +++++ .../video-virtio-blob-off.args | 34 +++++ .../video-virtio-blob-off.xml | 33 +++++ .../video-virtio-blob-on.args | 34 +++++ .../qemuxml2argvdata/video-virtio-blob-on.xml | 33 +++++ .../video-virtio-vga-blob-on.args | 34 +++++ .../video-virtio-vga-blob-on.xml | 33 +++++ tests/qemuxml2argvtest.c | 12 ++ .../video-virtio-blob-absent.xml | 41 ++++++ .../video-virtio-blob-off.xml | 41 ++++++ .../video-virtio-blob-on.xml | 41 ++++++ .../video-virtio-vga-blob-on.xml | 41 ++++++ tests/qemuxml2xmltest.c | 12 ++ 36 files changed, 652 insertions(+), 84 deletions(-) create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-absent.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-absent.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-off.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-off.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-on.args create mode 100644 tests/qemuxml2argvdata/video-virtio-blob-on.xml create mode 100644 tests/qemuxml2argvdata/video-virtio-vga-blob-on.args create mode 100644 tests/qemuxml2argvdata/video-virtio-vga-blob-on.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-absent.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-off.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-blob-on.xml create mode 100644 tests/qemuxml2xmloutdata/video-virtio-vga-blob-on.xml
participants (1)
-
Jonathon Jongsma