From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53175) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UjwLo-0006yc-BD for qemu-devel@nongnu.org; Tue, 04 Jun 2013 14:52:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UjwLm-0007DA-Fq for qemu-devel@nongnu.org; Tue, 04 Jun 2013 14:52:56 -0400 Received: from mail-wg0-x229.google.com ([2a00:1450:400c:c00::229]:44491) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UjwLm-0007Cs-9j for qemu-devel@nongnu.org; Tue, 04 Jun 2013 14:52:54 -0400 Received: by mail-wg0-f41.google.com with SMTP id k13so4166847wgh.2 for ; Tue, 04 Jun 2013 11:52:53 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Tue, 4 Jun 2013 20:51:58 +0200 Message-Id: <1370371954-8479-4-git-send-email-pbonzini@redhat.com> In-Reply-To: <1370371954-8479-1-git-send-email-pbonzini@redhat.com> References: <1370371954-8479-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 03/39] pci: split exit and finalize List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: mst@redhat.com To properly support devices that do DMA out of the BQL, destruction needs to be done in two phases. First, the device is unrealized; at this point, pending memory accesses can still be completed, but no new accesses will be started. The second part is freeing the device, which happens only after the reference count drops to zero; this means that all memory accesses are complete. This patch changes the PCI core to delay destruction of the bus-master address space and root region. Signed-off-by: Paolo Bonzini --- hw/pci/pci.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 776ad96..b60d9d0d 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -779,6 +779,16 @@ static void pci_config_free(PCIDevice *pci_dev) g_free(pci_dev->used); } +static void pci_device_instance_finalize(Object *obj) +{ + PCIDevice *pci_dev = PCI_DEVICE(obj); + + qemu_free_irqs(pci_dev->irq); + + address_space_destroy(&pci_dev->bus_master_as); + memory_region_destroy(&pci_dev->bus_master_enable_region); +} + /* -1 for devfn means auto assign */ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, const char *name, int devfn) @@ -866,12 +876,8 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, static void do_pci_unregister_device(PCIDevice *pci_dev) { - qemu_free_irqs(pci_dev->irq); pci_dev->bus->devices[pci_dev->devfn] = NULL; pci_config_free(pci_dev); - - address_space_destroy(&pci_dev->bus_master_as); - memory_region_destroy(&pci_dev->bus_master_enable_region); } static void pci_unregister_io_regions(PCIDevice *pci_dev) @@ -2243,6 +2249,7 @@ static const TypeInfo pci_device_type_info = { .abstract = true, .class_size = sizeof(PCIDeviceClass), .class_init = pci_device_class_init, + .instance_finalize = pci_device_instance_finalize, }; static void pci_register_types(void) -- 1.8.1.4