From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46378) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGlJM-0004vw-1b for qemu-devel@nongnu.org; Fri, 21 Feb 2014 03:18:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WGlJC-0001Qz-EP for qemu-devel@nongnu.org; Fri, 21 Feb 2014 03:18:19 -0500 Received: from e8.ny.us.ibm.com ([32.97.182.138]:51319) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGlJC-0001Qm-B2 for qemu-devel@nongnu.org; Fri, 21 Feb 2014 03:18:10 -0500 Received: from /spool/local by e8.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 21 Feb 2014 03:18:10 -0500 From: Michael Roth Date: Fri, 21 Feb 2014 02:16:48 -0600 Message-Id: <1392970647-21528-13-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1392970647-21528-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1392970647-21528-1-git-send-email-mdroth@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 12/51] virtio-pci: add device_unplugged callback List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: lersek@redhat.com, qemu-stable@nongnu.org, Petar.Jovanovic@imgtec.com From: Paolo Bonzini This fixes a crash in hot-unplug of virtio-pci devices behind a PCIe switch. The crash happens because the ioeventfd is still set whent the child is destroyed (destruction happens in postorder). Then the proxy tries to unset to ioeventfd, but the virtqueue structure that holds the EventNotifier has been trashed in the meanwhile. kvm_set_ioeventfd_pio does not expect failure and aborts. The fix is simply to move parts of uninitialization to a new device_unplugged callback, which is called before the child is destroyed. Cc: qemu-stable@nongnu.org Acked-by: Andreas Faerber Signed-off-by: Paolo Bonzini (cherry picked from commit 06a1307379fcd6c551185ad87679cd7ed896b9ea) Signed-off-by: Michael Roth --- hw/virtio/virtio-pci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 15b92e9..30c9f2b 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1002,6 +1002,15 @@ static void virtio_pci_device_plugged(DeviceState *d) proxy->host_features); } +static void virtio_pci_device_unplugged(DeviceState *d) +{ + PCIDevice *pci_dev = PCI_DEVICE(d); + VirtIOPCIProxy *proxy = VIRTIO_PCI(d); + + virtio_pci_stop_ioeventfd(proxy); + msix_uninit_exclusive_bar(pci_dev); +} + static int virtio_pci_init(PCIDevice *pci_dev) { VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev); @@ -1016,9 +1025,7 @@ static int virtio_pci_init(PCIDevice *pci_dev) static void virtio_pci_exit(PCIDevice *pci_dev) { VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev); - virtio_pci_stop_ioeventfd(proxy); memory_region_destroy(&proxy->bar); - msix_uninit_exclusive_bar(pci_dev); } static void virtio_pci_reset(DeviceState *qdev) @@ -1553,6 +1560,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data) k->set_guest_notifiers = virtio_pci_set_guest_notifiers; k->vmstate_change = virtio_pci_vmstate_change; k->device_plugged = virtio_pci_device_plugged; + k->device_unplugged = virtio_pci_device_unplugged; } static const TypeInfo virtio_pci_bus_info = { -- 1.7.9.5