diff mbox

q35: Fix memory_region_del_eventfd: Assertion `i != mr->ioeventfd_nb' failed.

Message ID 5384BD3B.4080904@gmail.com
State New
Headers show

Commit Message

Etienne Martineau May 27, 2014, 4:28 p.m. UTC
Hi,

When using virtio disk plug/unplug with q35 machine I see two problems. Note
that when using the same sequence with default 440FX I see no issues.

A) 'pcie.0' does not support hotplugging'

I can workaround this problem if I manually specify 
"-readconfig /usr/share/qemu/Q35-chipset.cfg" on the QEMU command line and
use the following monitor command to plug the disk:

(qemu) device_add virtio-blk-pci,id=device1,drive=drive1,scsi=on,bus=ich9-pcie-port-1

The content of Q35-chipset.cfg is:
[device "ich9-pcie-port-1"]
  driver = "ioh3420"
  multifunction = "on"
  bus = "pcie.0"

B) Upon disk unplug QEMU is crashing. This is with recent qemu.git. The following patch
solve the issue.

Signed-off-by: Etienne Martineau <etmartinau@gmail.com>
---
 hw/pci/pcie.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)
diff mbox

Patch

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 02cde6f..4cf8f4c 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -261,17 +261,31 @@  void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
     pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC);
 }
 
+/* Upon hot unplugged the device object must be stay until guest OS finish
+ * device removal ( at least for virtio-pci ). On non PCI Express there is no
+ * issue because the clean up is part of acpi_pcihp_eject_slot().
+ */
+static void pcie_cap_slot_hot_unplug_cleanup(void *opaque)
+{
+    DeviceState *dev = opaque;
+    object_unparent(OBJECT(dev));
+}
+
 void pcie_cap_slot_hot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
                                  Error **errp)
 {
     uint8_t *exp_cap;
+    QEMUTimer *timer;
 
     pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
 
-    object_unparent(OBJECT(dev));
     pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
                                  PCI_EXP_SLTSTA_PDS);
     pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC);
+
+    timer = timer_new_ms(QEMU_CLOCK_REALTIME, 
+                         pcie_cap_slot_hot_unplug_cleanup, dev);
+    timer_mod(timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000 );
 }
 
 /* pci express slot for pci express root/downstream port