<address bus='0x06' slot='0x02' function='0x0'/>
</source>
<boot order='1'/>
+ <rom bar='off'/>
</hostdev>
</devices>
...</pre>
used together with general boot elements in
<a href="#elementsOSBIOS">BIOS bootloader</a> section.
<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>
+ 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
+ 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.7</span>
+ </dd>
<dt><code>address</code></dt>
<dd>The <code>address</code> element for USB devices has a
<code>bus</code> and <code>device</code> attribute to specify the
<optional>
<ref name="address"/>
</optional>
+ <optional>
+ <element name="rom">
+ <attribute name="bar">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </attribute>
+ <empty/>
+ </element>
+ </optional>
</element>
</define>
<define name="usbproduct">
"usb",
"pci")
+VIR_ENUM_IMPL(virDomainPciRombarMode,
+ VIR_DOMAIN_PCI_ROMBAR_LAST,
+ "default",
+ "on",
+ "off")
+
VIR_ENUM_IMPL(virDomainHub, VIR_DOMAIN_HUB_TYPE_LAST,
"usb")
if (virDomainDeviceBootParseXML(cur, &def->bootIndex,
bootMap))
goto error;
+ } else if (xmlStrEqual(cur->name, BAD_CAST "rom")) {
+ char *rombar = virXMLPropString(cur, "bar");
+ if (!rombar) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ "%s", _("missing rom bar attribute"));
+ goto error;
+ }
+ if ((def->rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown rom bar value '%s'"), rombar);
+ VIR_FREE(rombar);
+ goto error;
+ }
+ VIR_FREE(rombar);
} else {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown node %s"), cur->name);
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
return -1;
+ if (def->rombar) {
+ const char *rombar
+ = virDomainPciRombarModeTypeToString(def->rombar);
+ if (!rombar) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected rom bar value %d"),
+ def->rombar);
+ return -1;
+ }
+ virBufferAsprintf(buf, " <rom bar='%s'/>\n", rombar);
+ }
+
virBufferAddLit(buf, " </hostdev>\n");
return 0;
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST
};
+enum virDomainPciRombarMode {
+ VIR_DOMAIN_PCI_ROMBAR_DEFAULT = 0,
+ VIR_DOMAIN_PCI_ROMBAR_ON,
+ VIR_DOMAIN_PCI_ROMBAR_OFF,
+
+ VIR_DOMAIN_PCI_ROMBAR_LAST
+};
+
typedef struct _virDomainHostdevDef virDomainHostdevDef;
typedef virDomainHostdevDef *virDomainHostdevDefPtr;
struct _virDomainHostdevDef {
} source;
int bootIndex;
virDomainDeviceInfo info; /* Guest address */
+ int rombar; /* enum virDomainPciRombarMode */
};
enum virDomainRedirdevBus {
VIR_ENUM_DECL(virDomainVideo)
VIR_ENUM_DECL(virDomainHostdevMode)
VIR_ENUM_DECL(virDomainHostdevSubsys)
+VIR_ENUM_DECL(virDomainPciRombarMode)
VIR_ENUM_DECL(virDomainHub)
VIR_ENUM_DECL(virDomainRedirdevBus)
VIR_ENUM_DECL(virDomainInput)
virDomainObjUnref;
virDomainPausedReasonTypeFromString;
virDomainPausedReasonTypeToString;
+virDomainPciRombarModeTypeFromString;
+virDomainPciRombarModeTypeToString;
virDomainRedirdevBusTypeFromString;
virDomainRedirdevBusTypeToString;
virDomainRemoveInactive;
"no-shutdown",
"cache-unsafe", /* 75 */
+ "rombar",
);
struct qemu_feature_flags {
if (version >= 13000)
qemuCapsSet(flags, QEMU_CAPS_PCI_MULTIFUNCTION);
+
+ /* Although very new versions of qemu advertise the presence of
+ * the rombar option in the output of "qemu -device pci-assign,?",
+ * this advertisement was added to the code long after the option
+ * itself. According to qemu developers, though, rombar is
+ * available in all qemu binaries from release 0.12 onward.
+ * Setting the capability this way makes it available in more
+ * cases where it might be needed, and shouldn't cause any false
+ * positives (in the case that it did, qemu would produce an error
+ * log and refuse to start, so it would be immediately obvious).
+ */
+ if (version >= 12000)
+ qemuCapsSet(flags, QEMU_CAPS_PCI_ROMBAR);
}
/* We parse the output of 'qemu -help' to get the QEMU
QEMU_CAPS_NO_SHUTDOWN = 74, /* usable -no-shutdown */
QEMU_CAPS_DRIVE_CACHE_UNSAFE = 75, /* Is cache=unsafe supported? */
+ QEMU_CAPS_PCI_ROMBAR = 76, /* -device rombar=0|1 */
QEMU_CAPS_LAST, /* this must always be the last item */
};
if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
goto error;
+ if (dev->rombar) {
+ if (!qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ "%s", _("rombar not supported in this QEMU binary"));
+ goto error;
+ }
+
+ switch (dev->rombar) {
+ case VIR_DOMAIN_PCI_ROMBAR_OFF:
+ virBufferAddLit(&buf, ",rombar=0");
+ break;
+ case VIR_DOMAIN_PCI_ROMBAR_ON:
+ virBufferAddLit(&buf, ",rombar=1");
+ break;
+ default:
+ break;
+ }
+ }
+
if (virBufferError(&buf)) {
virReportOOMError();
goto error;
QEMU_CAPS_VGA_NONE,
QEMU_CAPS_MIGRATE_QEMU_FD,
QEMU_CAPS_DRIVE_AIO,
- QEMU_CAPS_NO_SHUTDOWN);
+ QEMU_CAPS_NO_SHUTDOWN,
+ QEMU_CAPS_PCI_ROMBAR);
DO_TEST("qemu-kvm-0.12.1.2-rhel60", 12001, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
QEMU_CAPS_PIIX3_USB_UHCI,
QEMU_CAPS_PIIX4_USB_UHCI,
QEMU_CAPS_USB_HUB,
- QEMU_CAPS_NO_SHUTDOWN);
+ QEMU_CAPS_NO_SHUTDOWN,
+ QEMU_CAPS_PCI_ROMBAR);
DO_TEST("qemu-kvm-0.12.3", 12003, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
QEMU_CAPS_VGA_NONE,
QEMU_CAPS_MIGRATE_QEMU_FD,
QEMU_CAPS_DRIVE_AIO,
- QEMU_CAPS_NO_SHUTDOWN);
+ QEMU_CAPS_NO_SHUTDOWN,
+ QEMU_CAPS_PCI_ROMBAR);
DO_TEST("qemu-kvm-0.13.0", 13000, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
QEMU_CAPS_VT82C686B_USB_UHCI,
QEMU_CAPS_PCI_OHCI,
QEMU_CAPS_USB_HUB,
- QEMU_CAPS_NO_SHUTDOWN);
+ QEMU_CAPS_NO_SHUTDOWN,
+ QEMU_CAPS_PCI_ROMBAR);
DO_TEST("qemu-kvm-0.12.1.2-rhel61", 12001, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
QEMU_CAPS_PIIX3_USB_UHCI,
QEMU_CAPS_PIIX4_USB_UHCI,
QEMU_CAPS_USB_HUB,
- QEMU_CAPS_NO_SHUTDOWN);
+ QEMU_CAPS_NO_SHUTDOWN,
+ QEMU_CAPS_PCI_ROMBAR);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--- /dev/null
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
+/dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostdev0,\
+bus=pci.0,addr=0x3,rombar=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest2</name>
+ <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>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</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest2'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <hostdev mode='subsystem' type='pci' managed='yes'>
+ <source>
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
+ </source>
+ <rom bar='off'/>
+ </hostdev>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>