summary refs log tree commit diff stats
path: root/hw/pci
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2014-02-17 15:00:06 +0100
committerMichael S. Tsirkin <mst@redhat.com>2014-03-09 21:09:37 +0200
commit6e1f0a55a14bad1d0c8b9d29626ef4e4b2617c74 (patch)
tree60a890109fd1e4ceef52d35d86cb71fc2bc25dac /hw/pci
parent8e46bbf362458fc3e4638a53249248a1ee40b912 (diff)
downloadfocaccia-qemu-6e1f0a55a14bad1d0c8b9d29626ef4e4b2617c74.tar.gz
focaccia-qemu-6e1f0a55a14bad1d0c8b9d29626ef4e4b2617c74.zip
PCIE: fix regression with coldplugged multifunction device
PCIE is causing asserts each time a multifunction device is added
on command line (coldplug).

This is caused by
commit a66e657e18cd9b70e9f57ae5512c07faf2bc508f
    pci/pcie: convert PCIE hotplug to use hotplug-handler API
QEMU abort is caused by misplaced assertion, which should
be checked only when device is hotplugged.

Reference to regression report:
 http://www.mail-archive.com/qemu-devel@nongnu.org/msg216226.html

Fixes: a66e657e18cd9b70e9f57ae5512c07faf2bc508f

Reported-By: Nigel Kukard <nkukard+qemu@lbsd.net>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/pci')
-rw-r--r--hw/pci/pcie.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 8ecd11eca2..02cde6f96c 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -221,29 +221,23 @@ static void pcie_cap_slot_hotplug_common(PCIDevice *hotplug_dev,
                                          DeviceState *dev,
                                          uint8_t **exp_cap, Error **errp)
 {
-    PCIDevice *pci_dev = PCI_DEVICE(dev);
     *exp_cap = hotplug_dev->config + hotplug_dev->exp.exp_cap;
     uint16_t sltsta = pci_get_word(*exp_cap + PCI_EXP_SLTSTA);
 
-    PCIE_DEV_PRINTF(pci_dev, "hotplug state: %d\n", state);
+    PCIE_DEV_PRINTF(PCI_DEVICE(dev), "hotplug state: %d\n", state);
     if (sltsta & PCI_EXP_SLTSTA_EIS) {
         /* the slot is electromechanically locked.
          * This error is propagated up to qdev and then to HMP/QMP.
          */
         error_setg_errno(errp, -EBUSY, "slot is electromechanically locked");
     }
-
-    /* TODO: multifunction hot-plug.
-     * Right now, only a device of function = 0 is allowed to be
-     * hot plugged/unplugged.
-     */
-    assert(PCI_FUNC(pci_dev->devfn) == 0);
 }
 
 void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
                               Error **errp)
 {
     uint8_t *exp_cap;
+    PCIDevice *pci_dev = PCI_DEVICE(dev);
 
     pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
 
@@ -256,6 +250,12 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
         return;
     }
 
+    /* TODO: multifunction hot-plug.
+     * Right now, only a device of function = 0 is allowed to be
+     * hot plugged/unplugged.
+     */
+    assert(PCI_FUNC(pci_dev->devfn) == 0);
+
     pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
                                PCI_EXP_SLTSTA_PDS);
     pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC);