From 3801831cdf64cb040047b579d02942fe34ff31b5 Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Wed, 25 Jan 2012 11:20:49 -0500 Subject: [PATCH] qemu: add "romfile" support to specify device boot ROM This patch addresses: https://bugzilla.redhat.com/show_bug.cgi?id=781562 Along with the "rombar" option that controls whether or not a boot rom is made visible to the guest, qemu also has a "romfile" option that allows specifying a binary file to present as the ROM BIOS of any emulated or passthrough PCI device. This patch adds support for specifying romfile to both passthrough PCI devices, and emulated network devices that attach to the guest's PCI bus (just about everything other than ne2k_isa). One example of the usefulness of this option is described in the bugzilla report: 82576 sriov network adapters don't provide a ROM BIOS for the cards virtual functions (VF), but an image of such a ROM is available, and with this ROM visible to the guest, it can PXE boot. In libvirt's xml, the new option is configured like this: ... ... ). --- docs/formatdomain.html.in | 22 ++++++++--- docs/schemas/domaincommon.rng | 19 +++++++--- src/conf/domain_conf.c | 37 +++++++++++-------- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 8 ++-- .../qemuxml2argv-pci-rom.args | 7 ++-- .../qemuxml2argvdata/qemuxml2argv-pci-rom.xml | 3 +- 7 files changed, 63 insertions(+), 34 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e90e99f56..ab84730b8 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1741,7 +1741,7 @@ <address bus='0x06' slot='0x02' function='0x0'/> </source> <boot order='1'/> - <rom bar='off'/> + <rom bar='on' file='/etc/fake/boot.bin'/> </hostdev> </devices> ... @@ -1783,7 +1783,7 @@ Since 0.8.8
rom
The rom element is used to change how a PCI - device's ROM is presented to the guest. The bar + device's ROM is presented to the guest. The optional bar 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 @@ -1791,7 +1791,13 @@ 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"). Since - 0.9.7 + 0.9.7 (QEMU and KVM only). The optional + file 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). + Since 0.9.10 (QEMU and KVM only).
address
The address element for USB devices has a @@ -2492,7 +2498,7 @@ qemu-kvm -net nic,model=? /dev/null <interface type='network'> <source network='default'/> <target dev='vnet1'/> - <rom bar='off'/> + <rom bar='on' file='/etc/fake/boot.bin'/> </interface> </devices> ... @@ -2506,8 +2512,12 @@ qemu-kvm -net nic,model=? /dev/null 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"). Since - 0.9.10 (QEMU and KVM only) + have a default of "on"). + The optional file 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. + Since 0.9.10 (QEMU and KVM only).

Quality of service
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 755764143..ee4270ab5 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2818,12 +2818,19 @@ - - - on - off - - + + + + on + off + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b7f6913fe..4803cdf33 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1812,6 +1812,7 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) } memset(&info->addr, 0, sizeof(info->addr)); info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; + VIR_FREE(info->romfile); } @@ -1924,16 +1925,25 @@ virDomainDeviceInfoFormat(virBufferPtr buf, 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, " 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, " \n", rombar); + if (info->romfile) + virBufferAsprintf(buf, " file='%s'", info->romfile); + virBufferAddLit(buf, "/>\n"); } if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) @@ -2390,18 +2400,15 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, 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) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6419618b7..9a036853c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -170,6 +170,7 @@ struct _virDomainDeviceInfo { /* 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; }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3f60691b5..0e26df1cc 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1519,15 +1519,15 @@ qemuBuildRomStr(virBufferPtr buf, 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; } @@ -1541,6 +1541,8 @@ qemuBuildRomStr(virBufferPtr buf, default: break; } + if (info->romfile) + virBufferAsprintf(buf, ",romfile=%s", info->romfile); } return 0; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args index 1a46aa3c0..11e0f0f8e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args @@ -4,8 +4,9 @@ unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \ /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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml index 3f6b8deaf..731a69db7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml @@ -28,6 +28,7 @@ + @@ -39,7 +40,7 @@
- + -- 2.39.5