]> Git Repo - qemu.git/commitdiff
pci: give each device its own address space
authorAvi Kivity <[email protected]>
Wed, 3 Oct 2012 15:17:27 +0000 (17:17 +0200)
committerAvi Kivity <[email protected]>
Mon, 22 Oct 2012 12:50:08 +0000 (14:50 +0200)
Accesses from different devices can resolve differently
(depending on bridge settings, iommus, and PCI_COMMAND_MASTER), so
set up an address space for each device.

Currently iommus are expressed outside the memory API, so this doesn't
work if an iommu is present.

Signed-off-by: Avi Kivity <[email protected]>
hw/pci.c
hw/pci.h

index 2ca6ff6fecd43643d56fb1c0c11df469d791a580..b1415dbce6e8ca39c10cddf3dfcdccce323f7390 100644 (file)
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -33,6 +33,7 @@
 #include "qmp-commands.h"
 #include "msi.h"
 #include "msix.h"
+#include "exec-memory.h"
 
 //#define DEBUG_PCI
 #ifdef DEBUG_PCI
@@ -777,6 +778,13 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     pci_dev->bus = bus;
     if (bus->dma_context_fn) {
         pci_dev->dma = bus->dma_context_fn(bus, bus->dma_context_opaque, devfn);
+    } else {
+        /* FIXME: Make dma_context_fn use MemoryRegions instead, so this path is
+         * taken unconditionally */
+        /* FIXME: inherit memory region from bus creator */
+        address_space_init(&pci_dev->bus_master_as, get_system_memory());
+        pci_dev->dma = g_new(DMAContext, 1);
+        dma_context_init(pci_dev->dma, &pci_dev->bus_master_as, NULL, NULL, NULL);
     }
     pci_dev->devfn = devfn;
     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
@@ -830,6 +838,12 @@ 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);
+
+    if (!pci_dev->bus->dma_context_fn) {
+        address_space_destroy(&pci_dev->bus_master_as);
+        g_free(pci_dev->dma);
+        pci_dev->dma = NULL;
+    }
 }
 
 static void pci_unregister_io_regions(PCIDevice *pci_dev)
index d50d26c8ac3a8f5ec3f6d5daedd89317b70e8cf3..f9207ca062f2eac52379e201397feb54aef0c27a 100644 (file)
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -211,6 +211,7 @@ struct PCIDevice {
     int32_t devfn;
     char name[64];
     PCIIORegion io_regions[PCI_NUM_REGIONS];
+    AddressSpace bus_master_as;
     DMAContext *dma;
 
     /* do not access the following fields */
This page took 0.032679 seconds and 4 git commands to generate.