[PATCH v2 0/8] Expose QEMU's -fw_cfg

v2 of: https://www.redhat.com/archives/libvir-list/2020-June/msg00139.html diff to v1: - Changed domain XML, pre Dan's suggestion - Documented the feature in news Michal Prívozník (8): domain_conf: Format NS always last virSysinfoParseXML: Mangle ctxt inside virSysinfoParseXML() conf: Add firmware blob configuration qemu: Validate firmware blob configuration qemu: Introduce fw_cfg capability secdrivers: Relabel firmware config files qemu: Generate command line for -fw_cfg news: Document -fw_cfg docs/formatdomain.html.in | 32 +++ docs/news.xml | 12 ++ docs/schemas/domaincommon.rng | 143 +++++++------ src/conf/domain_conf.c | 195 +++++++++++++----- src/conf/domain_conf.h | 4 +- src/qemu/qemu_capabilities.c | 4 + src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_command.c | 54 ++++- src/qemu/qemu_validate.c | 40 ++++ src/security/security_dac.c | 50 +++++ src/security/security_selinux.c | 50 +++++ src/security/virt-aa-helper.c | 12 ++ src/util/virsysinfo.c | 54 ++++- src/util/virsysinfo.h | 16 +- .../caps_2.10.0.aarch64.xml | 1 + .../caps_2.10.0.ppc64.xml | 1 + .../caps_2.10.0.s390x.xml | 1 + .../caps_2.10.0.x86_64.xml | 1 + .../caps_2.11.0.s390x.xml | 1 + .../caps_2.11.0.x86_64.xml | 1 + .../caps_2.12.0.aarch64.xml | 1 + .../caps_2.12.0.ppc64.xml | 1 + .../caps_2.12.0.s390x.xml | 1 + .../caps_2.12.0.x86_64.xml | 1 + .../caps_2.4.0.x86_64.xml | 1 + .../caps_2.5.0.x86_64.xml | 1 + .../caps_2.6.0.aarch64.xml | 1 + .../qemucapabilitiesdata/caps_2.6.0.ppc64.xml | 1 + .../caps_2.6.0.x86_64.xml | 1 + .../qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 + .../caps_2.7.0.x86_64.xml | 1 + .../qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 + .../caps_2.8.0.x86_64.xml | 1 + .../qemucapabilitiesdata/caps_2.9.0.ppc64.xml | 1 + .../qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + .../caps_2.9.0.x86_64.xml | 1 + .../qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 1 + .../caps_3.0.0.riscv32.xml | 1 + .../caps_3.0.0.riscv64.xml | 1 + .../qemucapabilitiesdata/caps_3.0.0.s390x.xml | 1 + .../caps_3.0.0.x86_64.xml | 1 + .../qemucapabilitiesdata/caps_3.1.0.ppc64.xml | 1 + .../caps_3.1.0.x86_64.xml | 1 + .../caps_4.0.0.aarch64.xml | 1 + .../qemucapabilitiesdata/caps_4.0.0.ppc64.xml | 1 + .../caps_4.0.0.riscv32.xml | 1 + .../caps_4.0.0.riscv64.xml | 1 + .../qemucapabilitiesdata/caps_4.0.0.s390x.xml | 1 + .../caps_4.0.0.x86_64.xml | 1 + .../caps_4.1.0.x86_64.xml | 1 + .../caps_4.2.0.aarch64.xml | 1 + .../qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 1 + .../qemucapabilitiesdata/caps_4.2.0.s390x.xml | 1 + .../caps_4.2.0.x86_64.xml | 1 + .../caps_5.0.0.aarch64.xml | 1 + .../qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + .../caps_5.0.0.riscv64.xml | 1 + .../caps_5.0.0.x86_64.xml | 1 + .../caps_5.1.0.x86_64.xml | 1 + tests/qemuxml2argvdata/smbios-type-fwcfg.args | 38 ++++ tests/qemuxml2argvdata/smbios-type-fwcfg.xml | 63 ++++++ tests/qemuxml2argvtest.c | 1 + .../qemuxml2xmloutdata/smbios-type-fwcfg.xml | 1 + tests/qemuxml2xmltest.c | 1 + 64 files changed, 700 insertions(+), 118 deletions(-) create mode 100644 tests/qemuxml2argvdata/smbios-type-fwcfg.args create mode 100644 tests/qemuxml2argvdata/smbios-type-fwcfg.xml create mode 120000 tests/qemuxml2xmloutdata/smbios-type-fwcfg.xml -- 2.26.2

I think that since <qemu:commandline/> is kind of a hack, it doesn't deserve place in the front row. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1cdc7971fc..e84fbe1e21 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -29877,16 +29877,16 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, for (n = 0; n < def->nseclabels; n++) virSecurityLabelDefFormat(buf, def->seclabels[n], flags); - if (def->namespaceData && def->ns.format) { - if ((def->ns.format)(buf, def->namespaceData) < 0) - goto error; - } - if (def->keywrap) virDomainKeyWrapDefFormat(buf, def->keywrap); virDomainSEVDefFormat(buf, def->sev); + if (def->namespaceData && def->ns.format) { + if ((def->ns.format)(buf, def->namespaceData) < 0) + goto error; + } + virBufferAdjustIndent(buf, -2); virBufferAsprintf(buf, "</%s>\n", rootname); -- 2.26.2

On Thu, Jun 04, 2020 at 08:44:02PM +0200, Michal Privoznik wrote:
I think that since <qemu:commandline/> is kind of a hack, it doesn't deserve place in the front row.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

There's no need to set ctxt->node outside of the function. The function can set it itself - it has all the info needed. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e84fbe1e21..57a5b7befe 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -15714,10 +15714,13 @@ virSysinfoParseXML(xmlNodePtr node, unsigned char *domUUID, bool uuid_generated) { + VIR_XPATH_NODE_AUTORESTORE(ctxt); virSysinfoDefPtr def; xmlNodePtr tmpnode; g_autofree char *type = NULL; + ctxt->node = node; + if (!virXMLNodeNameEqual(node, "sysinfo")) { virReportError(VIR_ERR_XML_ERROR, "%s", _("XML does not contain expected 'sysinfo' element")); @@ -22179,8 +22182,6 @@ virDomainDefParseXML(xmlDocPtr xml, } if ((node = virXPathNode("./sysinfo[1]", ctxt)) != NULL) { - VIR_XPATH_NODE_AUTORESTORE(ctxt); - ctxt->node = node; def->sysinfo = virSysinfoParseXML(node, ctxt, def->uuid, uuid_generated); -- 2.26.2

On Thu, Jun 04, 2020 at 08:44:03PM +0200, Michal Privoznik wrote:
There's no need to set ctxt->node outside of the function. The function can set it itself - it has all the info needed.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

QEMU has -fw_cfg which allows users to tweak how firmware configures itself and/or provide new configuration blobs. Introduce new <sysinfo/> type "fwcfg" that will hold these new blobs. It's possible to either specify new value as a string or provide a filename which contents then serve as the value. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.html.in | 32 +++ docs/schemas/domaincommon.rng | 143 ++++++++------ src/conf/domain_conf.c | 186 +++++++++++++----- src/conf/domain_conf.h | 4 +- src/qemu/qemu_command.c | 10 +- src/util/virsysinfo.c | 54 ++++- src/util/virsysinfo.h | 16 +- tests/qemuxml2argvdata/smbios-type-fwcfg.xml | 63 ++++++ .../qemuxml2xmloutdata/smbios-type-fwcfg.xml | 1 + tests/qemuxml2xmltest.c | 1 + 10 files changed, 396 insertions(+), 114 deletions(-) create mode 100644 tests/qemuxml2argvdata/smbios-type-fwcfg.xml create mode 120000 tests/qemuxml2xmloutdata/smbios-type-fwcfg.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 33cec1e6dd..6e51aad8b1 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -479,6 +479,10 @@ <entry>otherappname:more arbitrary data</entry> </oemStrings> </sysinfo> +<sysinfo type='fwcfg'> + <entry name='opt/com.example/name' value='example value'/> + <entry name='opt/com.coreos/config' file='/tmp/provision.ign'/> +</sysinfo> ...</pre> <p> @@ -593,6 +597,34 @@ </dd> </dl> </dd> + + <dt><code>fwcfg</code></dt> + <dd> + Some hypervisors provide unified way to tweak how firmware configures + itself, or may contain tables to be installed for the guest OS, for + instance boot order, ACPI, SMBIOS, etc. It even allows users to define + their own config blobs. In case of QEMU, these then appear under domain's + sysfs, under <code>/sys/firmware/qemu_fw_cfg</code>. Note, that these + values apply regardless the <smbios/> mode under <os/>. + <span class="since">Since 6.5.0</span> + +<pre> + <smbios type='fwcfg'> + <entry name="opt/com.example/name" value="example value"/> + <entry name="opt/com.coreos/config" file="/tmp/provision.ign"/> + </smbios> +</pre> + + The <code>smbios</code> element can have multiple <code>entry</code> + child elements. Each element then has mandatory <code>name</code> + attribute, which defines the name of the blob and must begin with + <code>"opt/"</code> and to avoid clashing with other names is advised to + be in form <code>"opt/$RFQDN/$name"</code> where <code>$RFQDN</code> is a + reverse fully qualified domain name you control. + Then, the element can have either <code>value</code> attribute (to set + the blob value directly), or <code>file</code> attribute (to set the blob + value from the file). + </dd> </dl> <h3><a id="elementsCPUAllocation">CPU Allocation</a></h3> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 6727cd743b..9acf4b47d4 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -46,9 +46,9 @@ <optional> <ref name="cpu"/> </optional> - <optional> + <zeroOrMore> <ref name="sysinfo"/> - </optional> + </zeroOrMore> <ref name="os"/> <ref name="clock"/> <ref name="resources"/> @@ -5506,68 +5506,93 @@ --> <define name="sysinfo"> <element name="sysinfo"> - <attribute name="type"> - <value>smbios</value> - </attribute> - <interleave> - <optional> - <element name="bios"> - <oneOrMore> - <element name="entry"> - <attribute name="name"> - <ref name="sysinfo-bios-name"/> - </attribute> - <ref name="sysinfo-value"/> + <choice> + <group> + <attribute name="type"> + <value>smbios</value> + </attribute> + <interleave> + <optional> + <element name="bios"> + <oneOrMore> + <element name="entry"> + <attribute name="name"> + <ref name="sysinfo-bios-name"/> + </attribute> + <ref name="sysinfo-value"/> + </element> + </oneOrMore> </element> - </oneOrMore> - </element> - </optional> - <optional> - <element name="system"> - <oneOrMore> - <element name="entry"> - <attribute name="name"> - <ref name="sysinfo-system-name"/> - </attribute> - <ref name="sysinfo-value"/> + </optional> + <optional> + <element name="system"> + <oneOrMore> + <element name="entry"> + <attribute name="name"> + <ref name="sysinfo-system-name"/> + </attribute> + <ref name="sysinfo-value"/> + </element> + </oneOrMore> </element> - </oneOrMore> - </element> - </optional> - <zeroOrMore> - <element name="baseBoard"> - <oneOrMore> - <element name="entry"> - <attribute name="name"> - <ref name="sysinfo-baseBoard-name"/> - </attribute> - <ref name="sysinfo-value"/> + </optional> + <zeroOrMore> + <element name="baseBoard"> + <oneOrMore> + <element name="entry"> + <attribute name="name"> + <ref name="sysinfo-baseBoard-name"/> + </attribute> + <ref name="sysinfo-value"/> + </element> + </oneOrMore> </element> - </oneOrMore> - </element> - </zeroOrMore> - <optional> - <element name="chassis"> - <oneOrMore> - <element name="entry"> - <attribute name="name"> - <ref name="sysinfo-chassis-name"/> - </attribute> - <ref name="sysinfo-value"/> + </zeroOrMore> + <optional> + <element name="chassis"> + <oneOrMore> + <element name="entry"> + <attribute name="name"> + <ref name="sysinfo-chassis-name"/> + </attribute> + <ref name="sysinfo-value"/> + </element> + </oneOrMore> </element> - </oneOrMore> - </element> - </optional> - <optional> - <element name="oemStrings"> - <oneOrMore> - <element name="entry"> - <ref name="sysinfo-value"/> + </optional> + <optional> + <element name="oemStrings"> + <oneOrMore> + <element name="entry"> + <ref name="sysinfo-value"/> + </element> + </oneOrMore> </element> - </oneOrMore> - </element> - </optional> - </interleave> + </optional> + </interleave> + </group> + <group> + <attribute name="type"> + <value>fwcfg</value> + </attribute> + <zeroOrMore> + <element name="entry"> + <attribute name="name"> + <data type="string"/> + </attribute> + <choice> + <attribute name="value"> + <data type="string"/> + </attribute> + <attribute name="file"> + <data type="string"/> + </attribute> + </choice> + <empty/> + </element> + </zeroOrMore> + </group> + </choice> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 57a5b7befe..bed77f1dd7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3551,7 +3551,9 @@ void virDomainDefFree(virDomainDefPtr def) virDomainNumaFree(def->numa); - virSysinfoDefFree(def->sysinfo); + for (i = 0; i < def->nsysinfo; i++) + virSysinfoDefFree(def->sysinfo[i]); + VIR_FREE(def->sysinfo); virDomainRedirFilterDefFree(def->redirfilter); @@ -15708,67 +15710,146 @@ virSysinfoChassisParseXML(xmlNodePtr node, } -static virSysinfoDefPtr -virSysinfoParseXML(xmlNodePtr node, - xmlXPathContextPtr ctxt, - unsigned char *domUUID, - bool uuid_generated) +static int +virSysinfoParseSMBIOSDef(virSysinfoDefPtr def, + xmlXPathContextPtr ctxt, + unsigned char *domUUID, + bool uuid_generated) { - VIR_XPATH_NODE_AUTORESTORE(ctxt); - virSysinfoDefPtr def; xmlNodePtr tmpnode; - g_autofree char *type = NULL; - - ctxt->node = node; - - if (!virXMLNodeNameEqual(node, "sysinfo")) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("XML does not contain expected 'sysinfo' element")); - return NULL; - } - - if (VIR_ALLOC(def) < 0) - return NULL; - - type = virXMLPropString(node, "type"); - if (type == NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("sysinfo must contain a type attribute")); - goto error; - } - if ((def->type = virSysinfoTypeFromString(type)) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown sysinfo type '%s'"), type); - goto error; - } /* Extract BIOS related metadata */ if ((tmpnode = virXPathNode("./bios[1]", ctxt)) != NULL) { if (virSysinfoBIOSParseXML(tmpnode, ctxt, &def->bios) < 0) - goto error; + return -1; } /* Extract system related metadata */ if ((tmpnode = virXPathNode("./system[1]", ctxt)) != NULL) { if (virSysinfoSystemParseXML(tmpnode, ctxt, &def->system, domUUID, uuid_generated) < 0) - goto error; + return -1; } /* Extract system base board metadata */ if (virSysinfoBaseBoardParseXML(ctxt, &def->baseBoard, &def->nbaseBoard) < 0) - goto error; + return -1; /* Extract chassis related metadata */ if ((tmpnode = virXPathNode("./chassis[1]", ctxt)) != NULL) { if (virSysinfoChassisParseXML(tmpnode, ctxt, &def->chassis) < 0) - goto error; + return -1; } /* Extract system related metadata */ if ((tmpnode = virXPathNode("./oemStrings[1]", ctxt)) != NULL) { if (virSysinfoOEMStringsParseXML(tmpnode, ctxt, &def->oemStrings) < 0) + return -1; + } + + return 0; +} + + +static int +virSysinfoParseFWCfgDef(virSysinfoDefPtr def, + xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt); + g_autofree xmlNodePtr *nodes = NULL; + int n; + size_t i; + + ctxt->node = node; + + if ((n = virXPathNodeSet("./entry", ctxt, &nodes)) < 0) + return -1; + + if (n == 0) + return 0; + + def->fw_cfgs = g_new0(virSysinfoFWCfgDef, n); + + for (i = 0; i < n; i++) { + g_autofree char *name = NULL; + g_autofree char *value = NULL; + g_autofree char *file = NULL; + + if (!(name = virXMLPropString(nodes[i], "name"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Firmware entry is missing 'name' attribute")); + return -1; + } + + value = virXMLPropString(nodes[i], "value"); + file = virXMLPropString(nodes[i], "file"); + + if (!value && !file) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Firmware entry must have either 'value' or " + "'file' attribute")); + return -1; + } + + def->fw_cfgs[i].name = g_steal_pointer(&name); + def->fw_cfgs[i].value = g_steal_pointer(&value); + def->fw_cfgs[i].file = g_steal_pointer(&file); + def->nfw_cfgs++; + } + + return 0; +} + + +static virSysinfoDefPtr +virSysinfoParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + unsigned char *domUUID, + bool uuid_generated) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt); + virSysinfoDefPtr def; + g_autofree char *typeStr = NULL; + int type; + + ctxt->node = node; + + if (!virXMLNodeNameEqual(node, "sysinfo")) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("XML does not contain expected 'sysinfo' element")); + return NULL; + } + + if (VIR_ALLOC(def) < 0) + return NULL; + + typeStr = virXMLPropString(node, "type"); + if (typeStr == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("sysinfo must contain a type attribute")); + goto error; + } + if ((type = virSysinfoTypeFromString(typeStr)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown sysinfo type '%s'"), typeStr); + goto error; + } + def->type = type; + + switch (def->type) { + case VIR_SYSINFO_SMBIOS: + if (virSysinfoParseSMBIOSDef(def, ctxt, domUUID, uuid_generated) < 0) goto error; + break; + + case VIR_SYSINFO_FWCFG: + if (virSysinfoParseFWCfgDef(def, node, ctxt) < 0) + goto error; + break; + + case VIR_SYSINFO_LAST: + break; } return def; @@ -22173,6 +22254,7 @@ virDomainDefParseXML(xmlDocPtr xml, def->idmap.ngidmap = n; } + VIR_FREE(nodes); if ((def->idmap.uidmap && !def->idmap.gidmap) || (!def->idmap.uidmap && def->idmap.gidmap)) { @@ -22181,13 +22263,21 @@ virDomainDefParseXML(xmlDocPtr xml, goto error; } - if ((node = virXPathNode("./sysinfo[1]", ctxt)) != NULL) { - def->sysinfo = virSysinfoParseXML(node, ctxt, - def->uuid, uuid_generated); + if ((n = virXPathNodeSet("./sysinfo", ctxt, &nodes)) < 0) + goto error; - if (def->sysinfo == NULL) + def->sysinfo = g_new0(virSysinfoDefPtr, n); + + for (i = 0; i < n; i++) { + virSysinfoDefPtr sysinfo = virSysinfoParseXML(nodes[i], ctxt, + def->uuid, uuid_generated); + + if (!sysinfo) goto error; + + def->sysinfo[def->nsysinfo++] = sysinfo; } + VIR_FREE(nodes); if ((tmp = virXPathString("string(./os/smbios/@mode)", ctxt))) { int mode; @@ -24072,8 +24162,16 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src, if (!virCPUDefIsEqual(src->cpu, dst->cpu, true)) goto error; - if (!virSysinfoIsEqual(src->sysinfo, dst->sysinfo)) - goto error; + if (src->nsysinfo != dst->nsysinfo) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Target domain count of sysinfo does not match source")); + goto error; + } + + for (i = 0; i < src->nsysinfo; i++) { + if (!virSysinfoIsEqual(src->sysinfo[i], dst->sysinfo[i])) + goto error; + } if (src->ndisks != dst->ndisks) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -29507,8 +29605,8 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, if (def->resource) virDomainResourceDefFormat(buf, def->resource); - if (def->sysinfo) - ignore_value(virSysinfoFormat(buf, def->sysinfo)); + for (i = 0; i < def->nsysinfo; i++) + virSysinfoFormat(buf, def->sysinfo[i]); if (def->os.bootloader) { virBufferEscapeString(buf, "<bootloader>%s</bootloader>\n", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e152c599ca..bda8fb6bce 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2624,13 +2624,15 @@ struct _virDomainDef { size_t npanics; virDomainPanicDefPtr *panics; + size_t nsysinfo; + virSysinfoDefPtr *sysinfo; + /* Only 1 */ virDomainWatchdogDefPtr watchdog; virDomainMemballoonDefPtr memballoon; virDomainNVRAMDefPtr nvram; virDomainTPMDefPtr tpm; virCPUDefPtr cpu; - virSysinfoDefPtr sysinfo; virDomainRedirFilterDefPtr redirfilter; virDomainIOMMUDefPtr iommu; virDomainVsockDefPtr vsock; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 419eca5675..6eb577a68b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5736,13 +5736,19 @@ qemuBuildSmbiosCommandLine(virCommandPtr cmd, /* Host and guest uuid must differ, by definition of UUID. */ skip_uuid = true; } else if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_SYSINFO) { - if (def->sysinfo == NULL) { + for (i = 0; i < def->nsysinfo; i++) { + if (def->sysinfo[i]->type == VIR_SYSINFO_SMBIOS) { + source = def->sysinfo[i]; + break; + } + } + + if (!source) { virReportError(VIR_ERR_XML_ERROR, _("Domain '%s' sysinfo are not available"), def->name); return -1; } - source = def->sysinfo; /* domain_conf guaranteed that system_uuid matches guest uuid. */ } if (source != NULL) { diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c index 41f4d1cff9..50e42610ca 100644 --- a/src/util/virsysinfo.c +++ b/src/util/virsysinfo.c @@ -43,6 +43,7 @@ VIR_LOG_INIT("util.sysinfo"); VIR_ENUM_IMPL(virSysinfo, VIR_SYSINFO_LAST, "smbios", + "fwcfg" ); static const char *sysinfoDmidecode = DMIDECODE; @@ -1436,6 +1437,42 @@ virSysinfoOEMStringsFormat(virBufferPtr buf, virSysinfoOEMStringsDefPtr def) virBufferAddLit(buf, "</oemStrings>\n"); } + +static void +virSysinfoFormatSMBIOS(virBufferPtr buf, + virSysinfoDefPtr def) +{ + virSysinfoBIOSFormat(buf, def->bios); + virSysinfoSystemFormat(buf, def->system); + virSysinfoBaseBoardFormat(buf, def->baseBoard, def->nbaseBoard); + virSysinfoChassisFormat(buf, def->chassis); + virSysinfoProcessorFormat(buf, def); + virSysinfoMemoryFormat(buf, def); + virSysinfoOEMStringsFormat(buf, def->oemStrings); +} + + +static void +virSysinfoFormatFWCfg(virBufferPtr buf, + virSysinfoDefPtr def) +{ + size_t i; + + for (i = 0; i < def->nfw_cfgs; i++) { + const virSysinfoFWCfgDef *f = &def->fw_cfgs[i]; + + virBufferAsprintf(buf, "<entry name='%s' ", f->name); + + if (f->value) + virBufferEscapeString(buf, "value='%s'", f->value); + else + virBufferEscapeString(buf, "file='%s'", f->file); + + virBufferAddLit(buf, "/>\n"); + } +} + + /** * virSysinfoFormat: * @buf: buffer to append output to (may use auto-indentation) @@ -1458,13 +1495,16 @@ virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def) return -1; } - virSysinfoBIOSFormat(&childrenBuf, def->bios); - virSysinfoSystemFormat(&childrenBuf, def->system); - virSysinfoBaseBoardFormat(&childrenBuf, def->baseBoard, def->nbaseBoard); - virSysinfoChassisFormat(&childrenBuf, def->chassis); - virSysinfoProcessorFormat(&childrenBuf, def); - virSysinfoMemoryFormat(&childrenBuf, def); - virSysinfoOEMStringsFormat(&childrenBuf, def->oemStrings); + switch (def->type) { + case VIR_SYSINFO_SMBIOS: + virSysinfoFormatSMBIOS(&childrenBuf, def); + break; + case VIR_SYSINFO_FWCFG: + virSysinfoFormatFWCfg(&childrenBuf, def); + break; + case VIR_SYSINFO_LAST: + break; + } virBufferAsprintf(&attrBuf, " type='%s'", type); diff --git a/src/util/virsysinfo.h b/src/util/virsysinfo.h index f1d280e1c9..6b25969a4b 100644 --- a/src/util/virsysinfo.h +++ b/src/util/virsysinfo.h @@ -27,6 +27,7 @@ typedef enum { VIR_SYSINFO_SMBIOS, + VIR_SYSINFO_FWCFG, VIR_SYSINFO_LAST } virSysinfoType; @@ -112,11 +113,20 @@ struct _virSysinfoOEMStringsDef { char **values; }; +typedef struct _virSysinfoFWCfgDef virSysinfoFWCfgDef; +typedef virSysinfoFWCfgDef *virSysinfoFWCfgDefPtr; +struct _virSysinfoFWCfgDef { + char *name; + char *value; + char *file; +}; + typedef struct _virSysinfoDef virSysinfoDef; typedef virSysinfoDef *virSysinfoDefPtr; struct _virSysinfoDef { - int type; + virSysinfoType type; + /* The following members are valid for type == VIR_SYSINFO_SMBIOS */ virSysinfoBIOSDefPtr bios; virSysinfoSystemDefPtr system; @@ -132,6 +142,10 @@ struct _virSysinfoDef { virSysinfoMemoryDefPtr memory; virSysinfoOEMStringsDefPtr oemStrings; + + /* The following members are valid for type == VIR_SYSINFO_FWCFG */ + size_t nfw_cfgs; + virSysinfoFWCfgDefPtr fw_cfgs; }; virSysinfoDefPtr virSysinfoRead(void); diff --git a/tests/qemuxml2argvdata/smbios-type-fwcfg.xml b/tests/qemuxml2argvdata/smbios-type-fwcfg.xml new file mode 100644 index 0000000000..2644833b21 --- /dev/null +++ b/tests/qemuxml2argvdata/smbios-type-fwcfg.xml @@ -0,0 +1,63 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <sysinfo type='smbios'> + <bios> + <entry name='vendor'>LENOVO</entry> + <entry name='version'>6FET82WW (3.12 )</entry> + </bios> + <system> + <entry name='manufacturer'>Fedora</entry> + <entry name='product'>Virt-Manager</entry> + <entry name='version'>0.8.2-3.fc14</entry> + <entry name='serial'>32dfcb37-5af1-552b-357c-be8c3aa38310</entry> + <entry name='uuid'>c7a5fdbd-edaf-9455-926a-d65c16db1809</entry> + <entry name='sku'>1234567890</entry> + <entry name='family'>Red Hat</entry> + </system> + <baseBoard> + <entry name='manufacturer'>Lenovo</entry> + <entry name='product'>20BE0061MC</entry> + <entry name='version'>0B98401 Pro</entry> + <entry name='serial'>W1KS427111E</entry> + <entry name='location'>Not Available</entry> + </baseBoard> + </sysinfo> + <sysinfo type='fwcfg'> + <entry name='opt/com.example/name' value='example value'/> + <entry name='opt/com.coreos/config' file='/tmp/provision.ign'/> + </sysinfo> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + <smbios mode='sysinfo'/> + </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='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/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'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/smbios-type-fwcfg.xml b/tests/qemuxml2xmloutdata/smbios-type-fwcfg.xml new file mode 120000 index 0000000000..09a2682910 --- /dev/null +++ b/tests/qemuxml2xmloutdata/smbios-type-fwcfg.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/smbios-type-fwcfg.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index dcc7b29ded..157e686f2a 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1125,6 +1125,7 @@ mymain(void) DO_TEST("shmem-plain-doorbell", NONE); DO_TEST("smbios", NONE); DO_TEST("smbios-multiple-type2", NONE); + DO_TEST("smbios-type-fwcfg", NONE); DO_TEST_CAPS_LATEST("os-firmware-bios"); DO_TEST_CAPS_LATEST("os-firmware-efi"); -- 2.26.2

On Thu, Jun 04, 2020 at 08:44:04PM +0200, Michal Privoznik wrote:
QEMU has -fw_cfg which allows users to tweak how firmware configures itself and/or provide new configuration blobs. Introduce new <sysinfo/> type "fwcfg" that will hold these new blobs.
It's possible to either specify new value as a string or provide a filename which contents then serve as the value.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.html.in | 32 +++ docs/schemas/domaincommon.rng | 143 ++++++++------ src/conf/domain_conf.c | 186 +++++++++++++----- src/conf/domain_conf.h | 4 +- src/qemu/qemu_command.c | 10 +- src/util/virsysinfo.c | 54 ++++- src/util/virsysinfo.h | 16 +- tests/qemuxml2argvdata/smbios-type-fwcfg.xml | 63 ++++++ .../qemuxml2xmloutdata/smbios-type-fwcfg.xml | 1 + tests/qemuxml2xmltest.c | 1 + 10 files changed, 396 insertions(+), 114 deletions(-) create mode 100644 tests/qemuxml2argvdata/smbios-type-fwcfg.xml create mode 120000 tests/qemuxml2xmloutdata/smbios-type-fwcfg.xml diff --git a/tests/qemuxml2argvdata/smbios-type-fwcfg.xml b/tests/qemuxml2argvdata/smbios-type-fwcfg.xml new file mode 100644 index 0000000000..2644833b21 --- /dev/null +++ b/tests/qemuxml2argvdata/smbios-type-fwcfg.xml @@ -0,0 +1,63 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <sysinfo type='smbios'> + <bios> + <entry name='vendor'>LENOVO</entry> + <entry name='version'>6FET82WW (3.12 )</entry> + </bios> + <system> + <entry name='manufacturer'>Fedora</entry> + <entry name='product'>Virt-Manager</entry> + <entry name='version'>0.8.2-3.fc14</entry> + <entry name='serial'>32dfcb37-5af1-552b-357c-be8c3aa38310</entry> + <entry name='uuid'>c7a5fdbd-edaf-9455-926a-d65c16db1809</entry> + <entry name='sku'>1234567890</entry> + <entry name='family'>Red Hat</entry> + </system> + <baseBoard> + <entry name='manufacturer'>Lenovo</entry> + <entry name='product'>20BE0061MC</entry> + <entry name='version'>0B98401 Pro</entry> + <entry name='serial'>W1KS427111E</entry> + <entry name='location'>Not Available</entry> + </baseBoard> + </sysinfo> + <sysinfo type='fwcfg'> + <entry name='opt/com.example/name' value='example value'/> + <entry name='opt/com.coreos/config' file='/tmp/provision.ign'/> + </sysinfo>
I find it undesirable to use the value be the element contents in the SMBIOS case, and an attribute in fwcfg case. IOW I think we should be doing <sysinfo type='fwcfg'> <entry name='opt/com.example/name'>example value</value> <entry name='opt/com.coreos/config' file='/tmp/provision.ign'/> </sysinfo> Which is how we would have to retrofit a "file" attribute into the existing SMBIOS xml too Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

There are recommendations and limitations to the name of the config blobs we need to follow [1]. Firstly, we don't want users to change any value only add new blobs. This means, that the name must have "opt/" prefix and at the same time must not begin with "opt/ovmf" nor "opt/org.qemu" as these are reserved for OVMF or QEMU respectively. Secondly, there is a limit (FW_CFG_MAX_FILE_PATH in qemu.git) of 56 characters for filename. 1: docs/specs/fw_cfg.txt from qemu.git Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_validate.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 584d1375b8..56a7ebfd7f 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -762,6 +762,41 @@ qemuValidateDefGetVcpuHotplugGranularity(const virDomainDef *def) } +#define QEMU_FW_CFG_MAX_FILE_PATH 55 +static int +qemuValidateDomainDefSysinfo(const virSysinfoDef *def, + virQEMUCapsPtr qemuCaps G_GNUC_UNUSED) +{ + size_t i; + + for (i = 0; i < def->nfw_cfgs; i++) { + const virSysinfoFWCfgDef *f = &def->fw_cfgs[i]; + + if (!STRPREFIX(f->name, "opt/")) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Invalid firmware name")); + return -1; + } + + if (STRPREFIX(f->name, "opt/ovmf/") || + STRPREFIX(f->name, "opt/org.qemu/")) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("That firmware name is reserved")); + return -1; + } + + if (f->file && + strlen(f->file) > QEMU_FW_CFG_MAX_FILE_PATH) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("firmware file too long")); + return -1; + } + } + + return 0; +} + + int qemuValidateDomainDef(const virDomainDef *def, void *opaque) @@ -978,6 +1013,11 @@ qemuValidateDomainDef(const virDomainDef *def, } } + for (i = 0; i < def->nsysinfo; i++) { + if (qemuValidateDomainDefSysinfo(def->sysinfo[i], qemuCaps) < 0) + return -1; + } + return 0; } -- 2.26.2

On Thu, Jun 04, 2020 at 08:44:05PM +0200, Michal Privoznik wrote:
There are recommendations and limitations to the name of the config blobs we need to follow [1].
Firstly, we don't want users to change any value only add new blobs. This means, that the name must have "opt/" prefix and at the same time must not begin with "opt/ovmf" nor "opt/org.qemu" as these are reserved for OVMF or QEMU respectively.
Secondly, there is a limit (FW_CFG_MAX_FILE_PATH in qemu.git) of 56 characters for filename.
Ewww, that is horrible. I'm have inclined to say we should leave the limit unchecked in libvirt, and file a BZ against QEMU. It should be using g_strdup_printf() with filenames and not allocating on the stack. We already see peoiple exceeding the 100 charater limit of UNIX sockets, so a 56 character limit is going to be trivially exceeded without even trying hard.
1: docs/specs/fw_cfg.txt from qemu.git
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_validate.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 584d1375b8..56a7ebfd7f 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -762,6 +762,41 @@ qemuValidateDefGetVcpuHotplugGranularity(const virDomainDef *def) }
+#define QEMU_FW_CFG_MAX_FILE_PATH 55 +static int +qemuValidateDomainDefSysinfo(const virSysinfoDef *def, + virQEMUCapsPtr qemuCaps G_GNUC_UNUSED) +{ + size_t i; + + for (i = 0; i < def->nfw_cfgs; i++) { + const virSysinfoFWCfgDef *f = &def->fw_cfgs[i]; + + if (!STRPREFIX(f->name, "opt/")) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Invalid firmware name")); + return -1; + } + + if (STRPREFIX(f->name, "opt/ovmf/") || + STRPREFIX(f->name, "opt/org.qemu/")) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("That firmware name is reserved")); + return -1; + } + + if (f->file && + strlen(f->file) > QEMU_FW_CFG_MAX_FILE_PATH) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("firmware file too long")); + return -1; + } + } + + return 0; +} + + int qemuValidateDomainDef(const virDomainDef *def, void *opaque) @@ -978,6 +1013,11 @@ qemuValidateDomainDef(const virDomainDef *def, } }
+ for (i = 0; i < def->nsysinfo; i++) { + if (qemuValidateDomainDefSysinfo(def->sysinfo[i], qemuCaps) < 0) + return -1; + } + return 0; }
-- 2.26.2
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On 6/9/20 11:52 AM, Daniel P. Berrangé wrote:
On Thu, Jun 04, 2020 at 08:44:05PM +0200, Michal Privoznik wrote:
There are recommendations and limitations to the name of the config blobs we need to follow [1].
Firstly, we don't want users to change any value only add new blobs. This means, that the name must have "opt/" prefix and at the same time must not begin with "opt/ovmf" nor "opt/org.qemu" as these are reserved for OVMF or QEMU respectively.
Secondly, there is a limit (FW_CFG_MAX_FILE_PATH in qemu.git) of 56 characters for filename.
Ewww, that is horrible. I'm have inclined to say we should leave the limit unchecked in libvirt, and file a BZ against QEMU. It should be using g_strdup_printf() with filenames and not allocating on the stack. We already see peoiple exceeding the 100 charater limit of UNIX sockets, so a 56 character limit is going to be trivially exceeded without even trying hard.
Ah, I got it wrong when reading the documentation. The limit is the name of the entry, not file name associated. For instance the following works: -fw_cfg name=opt/com.example/blah,file=/tmp/some_very_long_path_that_is_more_than_fifty_six_characters_long_to_see_what_happens_if_I_do_that but if @name would be too long QEMU would fail: qemu-system-x86_64: -fw_cfg name=opt/com.example/some_very_long_...,file=...: name too long (max. 55 char) And this comes from kernel's implementation of qemu_fw_cfg. However, the name can be up to PAGE_SIZE long (minus 2 for terminating \n and NUL), according to sysfs documentation (Documentation/filesystems/sysfs.rst:241): - The buffer will always be PAGE_SIZE bytes in length. On i386, this is 4096. Given this new realization, I think I'll just remove the check and not fill bug. I don't think we need longer names, do we? Michal

On Tue, Jun 09, 2020 at 04:44:46PM +0200, Michal Privoznik wrote:
On 6/9/20 11:52 AM, Daniel P. Berrangé wrote:
On Thu, Jun 04, 2020 at 08:44:05PM +0200, Michal Privoznik wrote:
There are recommendations and limitations to the name of the config blobs we need to follow [1].
Firstly, we don't want users to change any value only add new blobs. This means, that the name must have "opt/" prefix and at the same time must not begin with "opt/ovmf" nor "opt/org.qemu" as these are reserved for OVMF or QEMU respectively.
Secondly, there is a limit (FW_CFG_MAX_FILE_PATH in qemu.git) of 56 characters for filename.
Ewww, that is horrible. I'm have inclined to say we should leave the limit unchecked in libvirt, and file a BZ against QEMU. It should be using g_strdup_printf() with filenames and not allocating on the stack. We already see peoiple exceeding the 100 charater limit of UNIX sockets, so a 56 character limit is going to be trivially exceeded without even trying hard.
Ah, I got it wrong when reading the documentation. The limit is the name of the entry, not file name associated. For instance the following works:
-fw_cfg name=opt/com.example/blah,file=/tmp/some_very_long_path_that_is_more_than_fifty_six_characters_long_to_see_what_happens_if_I_do_that
but if @name would be too long QEMU would fail:
qemu-system-x86_64: -fw_cfg name=opt/com.example/some_very_long_...,file=...: name too long (max. 55 char)
And this comes from kernel's implementation of qemu_fw_cfg. However, the name can be up to PAGE_SIZE long (minus 2 for terminating \n and NUL), according to sysfs documentation (Documentation/filesystems/sysfs.rst:241):
- The buffer will always be PAGE_SIZE bytes in length. On i386, this is 4096.
Given this new realization, I think I'll just remove the check and not fill bug. I don't think we need longer names, do we?
Yep, fine with me. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

This capability tracks whether QEMU supports -fw_cfg command line option, more specifically whether it allows specifying filename. There are some releases of QEMU which support -fw_cfg but not filename. If this is ever a problem we can refine the capability later on. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml | 1 + 47 files changed, 52 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index f12769635a..dbf8d6d45c 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -582,6 +582,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "tcg", "virtio-blk-pci.scsi.default.disabled", "pvscsi", + + /* 370 */ + "fw_cfg", ); @@ -3279,6 +3282,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = { { "overcommit", NULL, QEMU_CAPS_OVERCOMMIT }, { "smp-opts", "dies", QEMU_CAPS_SMP_DIES }, { "fsdev", "multidevs", QEMU_CAPS_FSDEV_MULTIDEVS }, + { "fw_cfg", "file", QEMU_CAPS_FW_CFG }, }; static int diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 076ecad0f7..7e5f007771 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -564,6 +564,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_DISABLED, /* virtio-blk-pci.scsi disabled by default */ QEMU_CAPS_SCSI_PVSCSI, /* -device pvscsi */ + /* 370 */ + QEMU_CAPS_FW_CFG, /* -fw_cfg command line option */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml index db8a298873..0848b1e18b 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml @@ -142,6 +142,7 @@ <flag name='iothread.poll-max-ns'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2010000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700287</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml index 15e8933300..82a37edd9c 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml @@ -142,6 +142,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2010000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900287</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml index 90c42cdf4f..7a1ad3d173 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml @@ -108,6 +108,7 @@ <flag name='query-cpu-model-comparison'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>2010000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100287</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml index cb02723ada..f82ea38a26 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml @@ -185,6 +185,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2010000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100287</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml index d27f656ae0..1108aa46d0 100644 --- a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml @@ -115,6 +115,7 @@ <flag name='query-cpu-model-comparison'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>2011000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100288</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml index 5245fc77dc..91cb5f80a6 100644 --- a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml @@ -191,6 +191,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2011000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100288</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml index 38d36400e4..78070c0401 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml @@ -158,6 +158,7 @@ <flag name='drive-nvme'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2012000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700289</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml index 53abf2debb..45d3baf080 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml @@ -159,6 +159,7 @@ <flag name='machine.pseries.cap-ibs'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2011090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900289</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml index 880e5f137a..f9b92d11f2 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml @@ -127,6 +127,7 @@ <flag name='drive-nvme'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>2012000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100289</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml index 319dd6f2c3..8688dc32d5 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml @@ -200,6 +200,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2011090</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100289</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml index 7f0fe3b9aa..310f69499f 100644 --- a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml @@ -136,6 +136,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2004000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml index efb4ffa019..af9b9e96fd 100644 --- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml @@ -142,6 +142,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2005000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml index 0ce5deb6e9..ec17ca5c27 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml @@ -125,6 +125,7 @@ <flag name='hda-output'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml index 13573cfd03..13e6df006e 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml @@ -121,6 +121,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml index 0c9f594a65..c25731997e 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml @@ -154,6 +154,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100244</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml index 571d748f6c..2421b46f35 100644 --- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml @@ -92,6 +92,7 @@ <flag name='zpci'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>2007000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100245</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml index c97fa18a1f..9f25bd17ec 100644 --- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml @@ -159,6 +159,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2007000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100245</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml index be5cf4977b..083562f641 100644 --- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml @@ -97,6 +97,7 @@ <flag name='query-cpu-model-comparison'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>2007093</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100246</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml index 9a2b1f83ac..5426e8a54b 100644 --- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml @@ -162,6 +162,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2008000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100246</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml index 0c32a1c305..fe49896e72 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml @@ -134,6 +134,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900247</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml index c93cd4211f..32861f67ba 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml @@ -102,6 +102,7 @@ <flag name='query-cpu-model-comparison'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100247</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml index 122d9509f1..f241cc7a59 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml @@ -179,6 +179,7 @@ <flag name='i8042'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100247</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml index b81ed605d3..95f982eadf 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml @@ -161,6 +161,7 @@ <flag name='machine.pseries.cap-ibs'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>2012050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900239</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml index e2c87dafe3..35d08c67ec 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml @@ -97,6 +97,7 @@ <flag name='drive-nvme'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>3000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml index 0b8e5589db..42635c2e6d 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml @@ -97,6 +97,7 @@ <flag name='drive-nvme'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>3000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml b/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml index 189bc09288..96d8953496 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml @@ -130,6 +130,7 @@ <flag name='drive-nvme'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>3000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100239</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml index 40cff641a8..80ab4914c6 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml @@ -206,6 +206,7 @@ <flag name='storage.werror'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>3000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100239</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml index 4e47e0a581..3a21eb3aab 100644 --- a/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml @@ -166,6 +166,7 @@ <flag name='machine.pseries.cap-ibs'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>3000091</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900240</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml index 3dbda4b3f3..b1f4794559 100644 --- a/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml @@ -209,6 +209,7 @@ <flag name='storage.werror'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>3000092</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100240</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml index 2b5210338f..b1047ca044 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml @@ -172,6 +172,7 @@ <flag name='storage.werror'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700240</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml index 582cbdc8c2..a4916c2279 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml @@ -180,6 +180,7 @@ <flag name='machine.pseries.cap-ibs'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900240</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml b/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml index 199911d254..ec7c6b05e1 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml @@ -173,6 +173,7 @@ <flag name='storage.werror'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml index 4ddb79d2f8..d8924a10e8 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml @@ -173,6 +173,7 @@ <flag name='storage.werror'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml b/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml index d04129c327..671c28cb82 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml @@ -138,6 +138,7 @@ <flag name='drive-nvme'/> <flag name='storage.werror'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100240</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml index bf7735caf3..a08a1655d4 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml @@ -214,6 +214,7 @@ <flag name='storage.werror'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100240</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml index 8ce0f80e8a..cde7b85428 100644 --- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml @@ -220,6 +220,7 @@ <flag name='storage.werror'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml index 154f70443e..11d487eefe 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml @@ -184,6 +184,7 @@ <flag name='virtio.packed'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml index eeec181f62..4d44cd4ac6 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml @@ -185,6 +185,7 @@ <flag name='machine.pseries.cap-ibs'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml b/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml index 4c0908294a..6db5926aaa 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml @@ -148,6 +148,7 @@ <flag name='fsdev.multidevs'/> <flag name='virtio.packed'/> <flag name='tcg'/> + <flag name='fw_cfg'/> <version>4002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>39100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml index 50ed35f092..fedd1ea13b 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml @@ -228,6 +228,7 @@ <flag name='virtio.packed'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>4002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml index 9b24490137..7f993b38e1 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml @@ -193,6 +193,7 @@ <flag name='tcg'/> <flag name='virtio-blk-pci.scsi.default.disabled'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml index 69e5b4c8fa..409120262e 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml @@ -201,6 +201,7 @@ <flag name='tcg'/> <flag name='virtio-blk-pci.scsi.default.disabled'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml index 7a091d27db..fb4956f144 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml @@ -189,6 +189,7 @@ <flag name='tcg'/> <flag name='virtio-blk-pci.scsi.default.disabled'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>0</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml index ba39fef713..d2c03444d5 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml @@ -234,6 +234,7 @@ <flag name='tcg'/> <flag name='virtio-blk-pci.scsi.default.disabled'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml index 3f538628b3..d1adcd6728 100644 --- a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml @@ -234,6 +234,7 @@ <flag name='tcg'/> <flag name='virtio-blk-pci.scsi.default.disabled'/> <flag name='pvscsi'/> + <flag name='fw_cfg'/> <version>5000050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> -- 2.26.2

On Thu, Jun 04, 2020 at 08:44:06PM +0200, Michal Privoznik wrote:
This capability tracks whether QEMU supports -fw_cfg command line option, more specifically whether it allows specifying filename.
There are some releases of QEMU which support -fw_cfg but not filename. If this is ever a problem we can refine the capability later on.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

For the case where -fw_cfg uses a file, we need to set the seclabels on it to allow QEMU the access. While QEMU allows writing into the file (if specified on the command line), so far we are enabling reading only and thus we can use read only label (in case of SELinux). Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/security/security_dac.c | 50 +++++++++++++++++++++++++++++++++ src/security/security_selinux.c | 50 +++++++++++++++++++++++++++++++++ src/security/virt-aa-helper.c | 12 ++++++++ 3 files changed, 112 insertions(+) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 7b95a6f86d..7e65b78fbe 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1916,6 +1916,24 @@ virSecurityDACRestoreSEVLabel(virSecurityManagerPtr mgr G_GNUC_UNUSED, } +static int +virSecurityDACRestoreSysinfoLabel(virSecurityManagerPtr mgr, + virSysinfoDefPtr def) +{ + size_t i; + + for (i = 0; i < def->nfw_cfgs; i++) { + virSysinfoFWCfgDefPtr f = &def->fw_cfgs[i]; + + if (f->file && + virSecurityDACRestoreFileLabel(mgr, f->file) < 0) + return -1; + } + + return 0; +} + + static int virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, @@ -1991,6 +2009,12 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr, rc = -1; } + for (i = 0; i < def->nsysinfo; i++) { + if (virSecurityDACRestoreSysinfoLabel(mgr, + def->sysinfo[i]) < 0) + rc = -1; + } + if (def->os.loader && def->os.loader->nvram && virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram) < 0) rc = -1; @@ -2094,6 +2118,27 @@ virSecurityDACSetSEVLabel(virSecurityManagerPtr mgr, } +static int +virSecurityDACSetSysinfoLabel(virSecurityManagerPtr mgr, + uid_t user, + gid_t group, + virSysinfoDefPtr def) +{ + size_t i; + + for (i = 0; i < def->nfw_cfgs; i++) { + virSysinfoFWCfgDefPtr f = &def->fw_cfgs[i]; + + if (f->file && + virSecurityDACSetOwnership(mgr, NULL, f->file, + user, group, true) < 0) + return -1; + } + + return 0; +} + + static int virSecurityDACSetAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, @@ -2173,6 +2218,11 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr, if (virSecurityDACGetImageIds(secdef, priv, &user, &group)) return -1; + for (i = 0; i < def->nsysinfo; i++) { + if (virSecurityDACSetSysinfoLabel(mgr, user, group, def->sysinfo[i]) < 0) + return -1; + } + if (def->os.loader && def->os.loader->nvram && virSecurityDACSetOwnership(mgr, NULL, def->os.loader->nvram, diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 7bb7c2b7b1..e6819af26c 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2720,6 +2720,24 @@ virSecuritySELinuxGetBaseLabel(virSecurityManagerPtr mgr, int virtType) } +static int +virSecuritySELinuxRestoreSysinfoLabel(virSecurityManagerPtr mgr, + virSysinfoDefPtr def) +{ + size_t i; + + for (i = 0; i < def->nfw_cfgs; i++) { + virSysinfoFWCfgDefPtr f = &def->fw_cfgs[i]; + + if (f->file && + virSecuritySELinuxRestoreFileLabel(mgr, f->file, true) < 0) + return -1; + } + + return 0; +} + + static int virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, @@ -2786,6 +2804,11 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr, mgr) < 0) rc = -1; + for (i = 0; i < def->nsysinfo; i++) { + if (virSecuritySELinuxRestoreSysinfoLabel(mgr, def->sysinfo[i]) < 0) + rc = -1; + } + if (def->os.loader && def->os.loader->nvram && virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram, true) < 0) rc = -1; @@ -3123,6 +3146,26 @@ virSecuritySELinuxSetSecuritySmartcardCallback(virDomainDefPtr def, } +static int +virSecuritySELinuxSetSysinfoLabel(virSecurityManagerPtr mgr, + virSysinfoDefPtr def, + virSecuritySELinuxDataPtr data) +{ + size_t i; + + for (i = 0; i < def->nfw_cfgs; i++) { + virSysinfoFWCfgDefPtr f = &def->fw_cfgs[i]; + + if (f->file && + virSecuritySELinuxSetFilecon(mgr, f->file, + data->content_context, true) < 0) + return -1; + } + + return 0; +} + + static int virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, @@ -3194,6 +3237,13 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr, mgr) < 0) return -1; + for (i = 0; i < def->nsysinfo; i++) { + if (virSecuritySELinuxSetSysinfoLabel(mgr, + def->sysinfo[i], + data) < 0) + return -1; + } + /* This is different than kernel or initrd. The nvram store * is really a disk, qemu can read and write to it. */ if (def->os.loader && def->os.loader->nvram && diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index 6e6dd1b1db..34c281100e 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -1175,6 +1175,18 @@ get_files(vahControl * ctl) } } + for (i = 0; i < ctl->def->nsysinfo; i++) { + size_t j; + + for (j = 0; j < ctl->def->sysinfo[i]->nfw_cfgs; j++) { + virSysinfoFWCfgDefPtr f = &ctl->def->sysinfo[i]->fw_cfgs[j]; + + if (f->file && + vah_add_file(&buf, f->file, "r") != 0) + goto cleanup; + } + } + for (i = 0; i < ctl->def->nshmems; i++) { virDomainShmemDef *shmem = ctl->def->shmems[i]; /* explicit server paths can be on any model to overwrites defaults. -- 2.26.2

On Thu, Jun 04, 2020 at 08:44:07PM +0200, Michal Privoznik wrote:
For the case where -fw_cfg uses a file, we need to set the seclabels on it to allow QEMU the access. While QEMU allows writing into the file (if specified on the command line), so far we are enabling reading only and thus we can use read only label (in case of SELinux).
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/security/security_dac.c | 50 +++++++++++++++++++++++++++++++++ src/security/security_selinux.c | 50 +++++++++++++++++++++++++++++++++ src/security/virt-aa-helper.c | 12 ++++++++ 3 files changed, 112 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

This is pretty straightforward and self explanatory. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1837990 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 44 +++++++++++++++++++ tests/qemuxml2argvdata/smbios-type-fwcfg.args | 38 ++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 3 files changed, 83 insertions(+) create mode 100644 tests/qemuxml2argvdata/smbios-type-fwcfg.args diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6eb577a68b..9d9b36adde 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5800,6 +5800,47 @@ qemuBuildSmbiosCommandLine(virCommandPtr cmd, } +static int +qemuBuildSysinfoCommandLine(virCommandPtr cmd, + virQEMUCapsPtr qemuCaps, + const virDomainDef *def) +{ + size_t i; + + /* We need to handle VIR_SYSINFO_FWCFG here, because + * VIR_SYSINFO_SMBIOS is handled in qemuBuildSmbiosCommandLine() */ + for (i = 0; i < def->nsysinfo; i++) { + size_t j; + + if (def->sysinfo[i]->type != VIR_SYSINFO_FWCFG) + continue; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_FW_CFG)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("fw_cfg is not supported with this QEMU")); + return -1; + } + + for (j = 0; j < def->sysinfo[i]->nfw_cfgs; j++) { + const virSysinfoFWCfgDef *f = &def->sysinfo[i]->fw_cfgs[j]; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + + virBufferAsprintf(&buf, "name=%s", f->name); + + if (f->value) + virBufferEscapeString(&buf, ",string=%s", f->value); + else + virBufferEscapeString(&buf, ",file=%s", f->file); + + virCommandAddArg(cmd, "-fw_cfg"); + virCommandAddArgBuffer(cmd, &buf); + } + } + + return 0; +} + + static int qemuBuildVMGenIDCommandLine(virCommandPtr cmd, const virDomainDef *def) @@ -9640,6 +9681,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildSmbiosCommandLine(cmd, driver, def) < 0) return NULL; + if (qemuBuildSysinfoCommandLine(cmd, qemuCaps, def) < 0) + return NULL; + if (qemuBuildVMGenIDCommandLine(cmd, def) < 0) return NULL; diff --git a/tests/qemuxml2argvdata/smbios-type-fwcfg.args b/tests/qemuxml2argvdata/smbios-type-fwcfg.args new file mode 100644 index 0000000000..372ae779b6 --- /dev/null +++ b/tests/qemuxml2argvdata/smbios-type-fwcfg.args @@ -0,0 +1,38 @@ +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 QEMUGuest1 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-smbios 'type=0,vendor=LENOVO,version=6FET82WW (3.12 )' \ +-smbios 'type=1,manufacturer=Fedora,product=Virt-Manager,version=0.8.2-3.fc14,\ +serial=32dfcb37-5af1-552b-357c-be8c3aa38310,\ +uuid=c7a5fdbd-edaf-9455-926a-d65c16db1809,sku=1234567890,family=Red Hat' \ +-smbios 'type=2,manufacturer=Lenovo,product=20BE0061MC,version=0B98401 Pro,\ +serial=W1KS427111E,location=Not Available' \ +-fw_cfg 'name=opt/com.example/name,string=example value' \ +-fw_cfg name=opt/com.coreos/config,file=/tmp/provision.ign \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 3103cac884..02f8846e57 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1684,6 +1684,7 @@ mymain(void) DO_TEST("smbios", NONE); DO_TEST_PARSE_ERROR("smbios-date", NONE); DO_TEST_PARSE_ERROR("smbios-uuid-match", NONE); + DO_TEST("smbios-type-fwcfg", QEMU_CAPS_FW_CFG); DO_TEST("watchdog", NONE); DO_TEST("watchdog-device", NONE); -- 2.26.2

On Thu, Jun 04, 2020 at 08:44:08PM +0200, Michal Privoznik wrote:
This is pretty straightforward and self explanatory.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1837990
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 44 +++++++++++++++++++ tests/qemuxml2argvdata/smbios-type-fwcfg.args | 38 ++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 3 files changed, 83 insertions(+) create mode 100644 tests/qemuxml2argvdata/smbios-type-fwcfg.args
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/news.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 18d96af048..d89ba778e1 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -44,6 +44,18 @@ <libvirt> <release version="v6.5.0" date="unreleased"> <section title="New features"> + <change> + <summary> + Allow firmware blobs configuration + </summary> + <description> + QEMU offers a way to tweak how firmware configures itself + and/or provide new configuration blobs. New <sysinfo/> + type is introduced that will hold these new blobs. + It's possible to either specify new value as a string or + provide a filename which contents then serve as the value. + </description> + </change> </section> <section title="Improvements"> </section> -- 2.26.2

On Thu, Jun 04, 2020 at 08:44:09PM +0200, Michal Privoznik wrote:
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/news.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
participants (2)
-
Daniel P. Berrangé
-
Michal Privoznik