conf: Add rom.enabled attribute for PCI devices

The attribute can be used to disable ROM loading completely
for a device.

This might be needed because, even when the guest is configured
such that the PCI ROM will not be loaded in the PCI BAR, some
hypervisors (eg. QEMU) might still make it available to the
guest in a form (eg. fw_cfg) that some firmwares (eg. SeaBIOS)
will consume, thus not achieving the desired result.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
This commit is contained in:
Andrea Bolognani 2018-04-19 17:55:41 +02:00
parent 868136624f
commit c4466179f4
4 changed files with 36 additions and 1 deletions

View File

@ -4476,6 +4476,12 @@
virtual function of an sr-iov capable ethernet device (which
has no boot ROMs for the VFs).
<span class="since">Since 0.9.10 (QEMU and KVM only)</span>.
The optional <code>enabled</code> attribute can be set to
<code>no</code> to disable PCI ROM loading completely for the device;
if PCI ROM loading is disabled through this attribute, attempts to
tweak the loading process further using the <code>bar</code> or
<code>file</code> attributes will be rejected.
<span class="since">Since 4.3.0 (QEMU and KVM only)</span>.
</dd>
<dt><code>address</code></dt>
<dd>The <code>address</code> element for USB devices has a

View File

@ -5108,6 +5108,11 @@
<define name="rom">
<element name="rom">
<optional>
<attribute name="enabled">
<ref name="virYesNo"/>
</attribute>
</optional>
<optional>
<attribute name="bar">
<ref name="virOnOff"/>

View File

@ -153,6 +153,7 @@ struct _virDomainDeviceInfo {
} master;
/* rombar and romfile are only used for pci hostdev and network
* devices. */
int romenabled; /* enum virTristateBool */
int rombar; /* enum virTristateSwitch */
char *romfile;
/* bootIndex is only used for disk, network interface, hostdev

View File

@ -6095,9 +6095,17 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
}
if ((flags & VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM) &&
(info->rombar != VIR_TRISTATE_SWITCH_ABSENT || info->romfile)) {
(info->romenabled != VIR_TRISTATE_BOOL_ABSENT ||
info->rombar != VIR_TRISTATE_SWITCH_ABSENT ||
info->romfile)) {
virBufferAddLit(buf, "<rom");
if (info->romenabled != VIR_TRISTATE_BOOL_ABSENT) {
const char *romenabled = virTristateBoolTypeToString(info->romenabled);
if (romenabled)
virBufferAsprintf(buf, " enabled='%s'", romenabled);
}
if (info->rombar != VIR_TRISTATE_SWITCH_ABSENT) {
const char *rombar = virTristateSwitchTypeToString(info->rombar);
@ -6738,6 +6746,7 @@ virDomainDeviceInfoParseXML(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED,
xmlNodePtr boot = NULL;
xmlNodePtr rom = NULL;
char *type = NULL;
char *romenabled = NULL;
char *rombar = NULL;
char *aliasStr = NULL;
int ret = -1;
@ -6791,6 +6800,12 @@ virDomainDeviceInfoParseXML(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED,
}
if (rom) {
if ((romenabled = virXMLPropString(rom, "enabled")) &&
((info->romenabled = virTristateBoolTypeFromString(romenabled)) <= 0)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown rom enabled value '%s'"), romenabled);
goto cleanup;
}
if ((rombar = virXMLPropString(rom, "bar")) &&
((info->rombar = virTristateSwitchTypeFromString(rombar)) <= 0)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@ -6798,6 +6813,13 @@ virDomainDeviceInfoParseXML(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED,
goto cleanup;
}
info->romfile = virXMLPropString(rom, "file");
if (info->romenabled == VIR_TRISTATE_BOOL_NO &&
(info->rombar != VIR_TRISTATE_SWITCH_ABSENT || info->romfile)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("ROM tuning is not supported when ROM is disabled"));
goto cleanup;
}
}
if (address &&
@ -6811,6 +6833,7 @@ virDomainDeviceInfoParseXML(virDomainXMLOptionPtr xmlopt ATTRIBUTE_UNUSED,
virDomainDeviceInfoClear(info);
VIR_FREE(type);
VIR_FREE(rombar);
VIR_FREE(romenabled);
VIR_FREE(aliasStr);
return ret;
}