<address bus='0x06' slot='0x02' function='0x0'/>
</source>
<boot order='1'/>
- <rom bar='off'/>
+ <rom bar='on' file='/etc/fake/boot.bin'/>
</hostdev>
</devices>
...</pre>
<span class="since">Since 0.8.8</span></dd>
<dt><code>rom</code></dt>
<dd>The <code>rom</code> element is used to change how a PCI
- device's ROM is presented to the guest. The <code>bar</code>
+ device's ROM is presented to the guest. The optional <code>bar</code>
attribute can be set to "on" or "off", and determines whether
or not the device's ROM will be visible in the guest's memory
map. (In PCI documentation, the "rombar" setting controls the
bar is specified, the qemu default will be used (older
versions of qemu used a default of "off", while newer qemus
have a default of "on"). <span class="since">Since
- 0.9.7</span>
+ 0.9.7 (QEMU and KVM only)</span>. The optional
+ <code>file</code> attribute is used to point to a binary file
+ to be presented to the guest as the device's ROM BIOS. This
+ can be useful, for example, to provide a PXE boot ROM for a
+ 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>.
</dd>
<dt><code>address</code></dt>
<dd>The <code>address</code> element for USB devices has a
<interface type='network'>
<source network='default'/>
<target dev='vnet1'/>
- <b><rom bar='off'/></b>
+ <b><rom bar='on' file='/etc/fake/boot.bin'/></b>
</interface>
</devices>
...</pre>
presence of the Base Address Register for the ROM). If no rom
bar is specified, the qemu default will be used (older
versions of qemu used a default of "off", while newer qemus
- have a default of "on"). <span class="since">Since
- 0.9.10 (QEMU and KVM only)</span>
+ have a default of "on").
+ The optional <code>file</code> attribute is used to point to a
+ binary file to be presented to the guest as the device's ROM
+ BIOS. This can be useful to provide an alternative boot ROM for a
+ network device.
+ <span class="since">Since 0.9.10 (QEMU and KVM only)</span>.
</p>
<h5><a name="elementQoS">Quality of service</a></h5>
<define name="rom">
<element name="rom">
- <attribute name="bar">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
+ <optional>
+ <attribute name="bar">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="file">
+ <ref name="absFilePath"/>
+ </attribute>
+ </optional>
<empty/>
</element>
</define>
}
memset(&info->addr, 0, sizeof(info->addr));
info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE;
+ VIR_FREE(info->romfile);
}
info->master.usb.startport);
}
- if ((flags & VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) && info->rombar) {
- const char *rombar
- = virDomainPciRombarModeTypeToString(info->rombar);
- if (!rombar) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected rom bar value %d"),
- info->rombar);
- return -1;
+ if ((flags & VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) &&
+ (info->rombar || info->romfile)) {
+
+ virBufferAddLit(buf, " <rom");
+ if (info->rombar) {
+
+ const char *rombar = virDomainPciRombarModeTypeToString(info->rombar);
+
+ if (!rombar) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected rom bar value %d"),
+ info->rombar);
+ return -1;
+ }
+ virBufferAsprintf(buf, " bar='%s'", rombar);
}
- virBufferAsprintf(buf, " <rom bar='%s'/>\n", rombar);
+ if (info->romfile)
+ virBufferAsprintf(buf, " file='%s'", info->romfile);
+ virBufferAddLit(buf, "/>\n");
}
if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
if (rom) {
char *rombar = virXMLPropString(rom, "bar");
- if (!rombar) {
- virDomainReportError(VIR_ERR_XML_ERROR,
- "%s", _("missing rom bar attribute"));
- goto cleanup;
- }
- if ((info->rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0) {
+ if (rombar &&
+ ((info->rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0)) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown rom bar value '%s'"), rombar);
VIR_FREE(rombar);
goto cleanup;
}
VIR_FREE(rombar);
+ info->romfile = virXMLPropString(rom, "file");
}
if (!address)
/* rombar is only used for pci hostdev devices, and bootIndex only
* for disk, network interface, and hostdev devices */
int rombar; /* enum virDomainPciRombarMode */
+ char *romfile;
int bootIndex;
};
virDomainDeviceInfoPtr info,
virBitmapPtr qemuCaps)
{
- if (info->rombar) {
+ if (info->rombar || info->romfile) {
if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("rombar is supported only for PCI devices"));
+ "%s", _("rombar and romfile are supported only for PCI devices"));
return -1;
}
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("rombar not supported in this QEMU binary"));
+ "%s", _("rombar and romfile not supported in this QEMU binary"));
return -1;
}
default:
break;
}
+ if (info->romfile)
+ virBufferAsprintf(buf, ",romfile=%s", info->romfile);
}
return 0;
}
/dev/HostVG/QEMUGuest2 \
-device virtio-net-pci,vlan=0,id=net0,mac=52:54:00:24:a5:9f,bus=pci.0,addr=0x3,rombar=1 \
-net user,vlan=0,name=hostnet0 \
--device virtio-net-pci,vlan=1,id=net1,mac=52:54:00:24:a5:9e,bus=pci.0,addr=0x4 \
--net user,vlan=1,name=hostnet1 \
+-device virtio-net-pci,vlan=1,id=net1,mac=52:54:00:24:a5:9e,bus=pci.0,addr=0x4,\
+romfile=/etc/fake/bootrom.bin -net user,vlan=1,name=hostnet1 \
-usb -device pci-assign,host=06:12.5,id=hostdev0,bus=pci.0,addr=0x5,rombar=0 \
--device pci-assign,host=06:12.6,id=hostdev1,bus=pci.0,addr=0x6,rombar=1 \
+-device pci-assign,host=06:12.6,id=hostdev1,bus=pci.0,addr=0x6,rombar=1,\
+romfile=/etc/fake/bootrom.bin \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7
<interface type='user'>
<mac address='52:54:00:24:a5:9e'/>
<model type='virtio'/>
+ <rom file='/etc/fake/bootrom.bin'/>
</interface>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<source>
<address domain='0x0000' bus='0x06' slot='0x12' function='0x6'/>
</source>
- <rom bar='on'/>
+ <rom bar='on' file='/etc/fake/bootrom.bin'/>
</hostdev>
<memballoon model='virtio'/>
</devices>