Patchwork Do not try loading option ROM for hotplug PCI device in pc-0.11 compat mode

login
register
mail settings
Submitter Jes Sorensen
Date July 23, 2010, 12:17 p.m.
Message ID <1279887427-4785-1-git-send-email-Jes.Sorensen@redhat.com>
Download mbox | patch
Permalink /patch/59777/
State New
Headers show

Comments

Jes Sorensen - July 23, 2010, 12:17 p.m.
From: Jes Sorensen <Jes.Sorensen@redhat.com>

pc-0.11 and older uses fw_cfg to provide option ROMs. As fw_cfg is setup
at init time, it is not possible to load an option ROM for a hotplug
device when running in compat mode.

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
---
 hw/pci.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)
Markus Armbruster - July 23, 2010, 3:37 p.m.
Jes.Sorensen@redhat.com writes:

> From: Jes Sorensen <Jes.Sorensen@redhat.com>
>
> pc-0.11 and older uses fw_cfg to provide option ROMs. As fw_cfg is setup
> at init time, it is not possible to load an option ROM for a hotplug
> device when running in compat mode.

Example:

    $ qemu -M pc-0.11 -S -monitor stdio
    QEMU 0.12.50 monitor - type 'help' for more information
    (qemu) device_add e1000
    qemu: hardware error: ROM images must be loaded at startup
[...]
    Aborted (core dumped)

The fix silently omits the option ROM when we can't load it.  Works for
me.

Patch

diff --git a/hw/pci.c b/hw/pci.c
index a98d6f3..12bd4aa 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -77,7 +77,7 @@  static struct BusInfo pci_bus_info = {
 
 static void pci_update_mappings(PCIDevice *d);
 static void pci_set_irq(void *opaque, int irq_num, int level);
-static int pci_add_option_rom(PCIDevice *pdev);
+static int pci_add_option_rom(PCIDevice *pdev, int hotplugged);
 static void pci_del_option_rom(PCIDevice *pdev);
 
 static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
@@ -1693,7 +1693,7 @@  static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
     /* rom loading */
     if (pci_dev->romfile == NULL && info->romfile != NULL)
         pci_dev->romfile = qemu_strdup(info->romfile);
-    pci_add_option_rom(pci_dev);
+    pci_add_option_rom(pci_dev, qdev->hotplugged);
 
     if (qdev->hotplugged) {
         rc = bus->hotplug(bus->hotplug_qdev, pci_dev, 1);
@@ -1797,7 +1797,7 @@  static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, p
 }
 
 /* Add an option rom for the device */
-static int pci_add_option_rom(PCIDevice *pdev)
+static int pci_add_option_rom(PCIDevice *pdev, int hotplugged)
 {
     int size;
     char *path;
@@ -1810,11 +1810,15 @@  static int pci_add_option_rom(PCIDevice *pdev)
         return 0;
 
     if (!pdev->rom_bar) {
+        int class;
         /*
          * Load rom via fw_cfg instead of creating a rom bar,
-         * for 0.11 compatibility.
+         * for 0.11 compatibility. fw_cfg is initialized at boot, so
+         * we cannot do hotplug load of option roms.
          */
-        int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
+        if (hotplugged)
+            return 0;
+        class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
         if (class == 0x0300) {
             rom_add_vga(pdev->romfile);
         } else {