summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-10-22 13:26:07 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2012-10-22 13:26:07 -0500
commitd3e2efc5b540c4e99ed5bcc0db3b1158ef52af43 (patch)
tree99bdc14357f131ce43ec8309d677a04285a9fa42 /hw
parentf354b1a1ee7a1c72d51b42808724a2b10eec315f (diff)
parent1c380f9460522f32c8dd2577b2a53d518ec91c6d (diff)
downloadhqemu-d3e2efc5b540c4e99ed5bcc0db3b1158ef52af43.zip
hqemu-d3e2efc5b540c4e99ed5bcc0db3b1158ef52af43.tar.gz
Merge remote-tracking branch 'qemu-kvm/memory/dma' into staging
* qemu-kvm/memory/dma: (23 commits) pci: honor PCI_COMMAND_MASTER pci: give each device its own address space memory: add address_space_destroy() dma: make dma access its own address space memory: per-AddressSpace dispatch s390: avoid reaching into memory core internals memory: use AddressSpace for MemoryListener filtering memory: move tcg flush into a tcg memory listener memory: move address_space_memory and address_space_io out of memory core memory: manage coalesced mmio via a MemoryListener xen: drop no-op MemoryListener callbacks kvm: drop no-op MemoryListener callbacks xen_pt: drop no-op MemoryListener callbacks vfio: drop no-op MemoryListener callbacks memory: drop no-op MemoryListener callbacks memory: provide defaults for MemoryListener operations memory: maintain a list of address spaces memory: export AddressSpace memory: prepare AddressSpace for exporting xen_pt: use separate MemoryListeners for memory and I/O ...
Diffstat (limited to 'hw')
-rw-r--r--hw/pci.c25
-rw-r--r--hw/pci.h2
-rw-r--r--hw/spapr_iommu.c3
-rw-r--r--hw/vfio_pci.c32
-rw-r--r--hw/vhost.c5
-rw-r--r--hw/xen_pt.c47
-rw-r--r--hw/xen_pt.h1
7 files changed, 51 insertions, 64 deletions
diff --git a/hw/pci.c b/hw/pci.c
index 2ca6ff6..7eeaac0 100644
--- 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,17 @@ 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 */
+ memory_region_init_alias(&pci_dev->bus_master_enable_region, "bus master",
+ get_system_memory(), 0,
+ memory_region_size(get_system_memory()));
+ memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
+ address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region);
+ 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 +842,13 @@ 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);
+ memory_region_destroy(&pci_dev->bus_master_enable_region);
+ g_free(pci_dev->dma);
+ pci_dev->dma = NULL;
+ }
}
static void pci_unregister_io_regions(PCIDevice *pci_dev)
@@ -1051,8 +1070,12 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
range_covers_byte(addr, l, PCI_COMMAND))
pci_update_mappings(d);
- if (range_covers_byte(addr, l, PCI_COMMAND))
+ if (range_covers_byte(addr, l, PCI_COMMAND)) {
pci_update_irq_disabled(d, was_irq_disabled);
+ memory_region_set_enabled(&d->bus_master_enable_region,
+ pci_get_word(d->config + PCI_COMMAND)
+ & PCI_COMMAND_MASTER);
+ }
msi_write_config(d, addr, val, l);
msix_write_config(d, addr, val, l);
diff --git a/hw/pci.h b/hw/pci.h
index d50d26c..1f902f5 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -211,6 +211,8 @@ struct PCIDevice {
int32_t devfn;
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
+ AddressSpace bus_master_as;
+ MemoryRegion bus_master_enable_region;
DMAContext *dma;
/* do not access the following fields */
diff --git a/hw/spapr_iommu.c b/hw/spapr_iommu.c
index 38034c0..33f84e2 100644
--- a/hw/spapr_iommu.c
+++ b/hw/spapr_iommu.c
@@ -21,6 +21,7 @@
#include "qdev.h"
#include "kvm_ppc.h"
#include "dma.h"
+#include "exec-memory.h"
#include "hw/spapr.h"
@@ -124,7 +125,7 @@ DMAContext *spapr_tce_new_dma_context(uint32_t liobn, size_t window_size)
}
tcet = g_malloc0(sizeof(*tcet));
- dma_context_init(&tcet->dma, spapr_tce_translate, NULL, NULL);
+ dma_context_init(&tcet->dma, &address_space_memory, spapr_tce_translate, NULL, NULL);
tcet->liobn = liobn;
tcet->window_size = window_size;
diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 639371e..f5db4a8 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -930,25 +930,6 @@ static int vfio_dma_map(VFIOContainer *container, target_phys_addr_t iova,
return -errno;
}
-static void vfio_listener_dummy1(MemoryListener *listener)
-{
- /* We don't do batching (begin/commit) or care about logging */
-}
-
-static void vfio_listener_dummy2(MemoryListener *listener,
- MemoryRegionSection *section)
-{
- /* We don't do logging or care about nops */
-}
-
-static void vfio_listener_dummy3(MemoryListener *listener,
- MemoryRegionSection *section,
- bool match_data, uint64_t data,
- EventNotifier *e)
-{
- /* We don't care about eventfds */
-}
-
static bool vfio_listener_skipped_section(MemoryRegionSection *section)
{
return !memory_region_is_ram(section->mr);
@@ -1040,18 +1021,8 @@ static void vfio_listener_region_del(MemoryListener *listener,
}
static MemoryListener vfio_memory_listener = {
- .begin = vfio_listener_dummy1,
- .commit = vfio_listener_dummy1,
.region_add = vfio_listener_region_add,
.region_del = vfio_listener_region_del,
- .region_nop = vfio_listener_dummy2,
- .log_start = vfio_listener_dummy2,
- .log_stop = vfio_listener_dummy2,
- .log_sync = vfio_listener_dummy2,
- .log_global_start = vfio_listener_dummy1,
- .log_global_stop = vfio_listener_dummy1,
- .eventfd_add = vfio_listener_dummy3,
- .eventfd_del = vfio_listener_dummy3,
};
static void vfio_listener_release(VFIOContainer *container)
@@ -1536,8 +1507,7 @@ static int vfio_connect_container(VFIOGroup *group)
container->iommu_data.listener = vfio_memory_listener;
container->iommu_data.release = vfio_listener_release;
- memory_listener_register(&container->iommu_data.listener,
- get_system_memory());
+ memory_listener_register(&container->iommu_data.listener, &address_space_memory);
} else {
error_report("vfio: No available IOMMU models\n");
g_free(container);
diff --git a/hw/vhost.c b/hw/vhost.c
index d0ce5aa..0b4ac3f 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -434,8 +434,7 @@ static void vhost_set_memory(MemoryListener *listener,
static bool vhost_section(MemoryRegionSection *section)
{
- return section->address_space == get_system_memory()
- && memory_region_is_ram(section->mr);
+ return memory_region_is_ram(section->mr);
}
static void vhost_begin(MemoryListener *listener)
@@ -793,7 +792,7 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath,
hdev->log_size = 0;
hdev->log_enabled = false;
hdev->started = false;
- memory_listener_register(&hdev->memory_listener, NULL);
+ memory_listener_register(&hdev->memory_listener, &address_space_memory);
hdev->force = force;
return 0;
fail:
diff --git a/hw/xen_pt.c b/hw/xen_pt.c
index 838bcea..d3d7c8b 100644
--- a/hw/xen_pt.c
+++ b/hw/xen_pt.c
@@ -59,6 +59,7 @@
#include "xen_backend.h"
#include "xen_pt.h"
#include "range.h"
+#include "exec-memory.h"
#define XEN_PT_NR_IRQS (256)
static uint8_t xen_pt_mapped_machine_irq[XEN_PT_NR_IRQS] = {0};
@@ -600,14 +601,6 @@ static void xen_pt_region_update(XenPCIPassthroughState *s,
}
}
-static void xen_pt_begin(MemoryListener *l)
-{
-}
-
-static void xen_pt_commit(MemoryListener *l)
-{
-}
-
static void xen_pt_region_add(MemoryListener *l, MemoryRegionSection *sec)
{
XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
@@ -624,36 +617,31 @@ static void xen_pt_region_del(MemoryListener *l, MemoryRegionSection *sec)
xen_pt_region_update(s, sec, false);
}
-static void xen_pt_region_nop(MemoryListener *l, MemoryRegionSection *s)
+static void xen_pt_io_region_add(MemoryListener *l, MemoryRegionSection *sec)
{
-}
+ XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
+ io_listener);
-static void xen_pt_log_fns(MemoryListener *l, MemoryRegionSection *s)
-{
+ xen_pt_region_update(s, sec, true);
}
-static void xen_pt_log_global_fns(MemoryListener *l)
+static void xen_pt_io_region_del(MemoryListener *l, MemoryRegionSection *sec)
{
-}
+ XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
+ io_listener);
-static void xen_pt_eventfd_fns(MemoryListener *l, MemoryRegionSection *s,
- bool match_data, uint64_t data, EventNotifier *n)
-{
+ xen_pt_region_update(s, sec, false);
}
static const MemoryListener xen_pt_memory_listener = {
- .begin = xen_pt_begin,
- .commit = xen_pt_commit,
.region_add = xen_pt_region_add,
- .region_nop = xen_pt_region_nop,
.region_del = xen_pt_region_del,
- .log_start = xen_pt_log_fns,
- .log_stop = xen_pt_log_fns,
- .log_sync = xen_pt_log_fns,
- .log_global_start = xen_pt_log_global_fns,
- .log_global_stop = xen_pt_log_global_fns,
- .eventfd_add = xen_pt_eventfd_fns,
- .eventfd_del = xen_pt_eventfd_fns,
+ .priority = 10,
+};
+
+static const MemoryListener xen_pt_io_listener = {
+ .region_add = xen_pt_io_region_add,
+ .region_del = xen_pt_io_region_del,
.priority = 10,
};
@@ -694,6 +682,7 @@ static int xen_pt_initfn(PCIDevice *d)
}
s->memory_listener = xen_pt_memory_listener;
+ s->io_listener = xen_pt_io_listener;
/* Handle real device's MMIO/PIO BARs */
xen_pt_register_regions(s);
@@ -760,7 +749,8 @@ static int xen_pt_initfn(PCIDevice *d)
}
out:
- memory_listener_register(&s->memory_listener, NULL);
+ memory_listener_register(&s->memory_listener, &address_space_memory);
+ memory_listener_register(&s->io_listener, &address_space_io);
XEN_PT_LOG(d, "Real physical device %02x:%02x.%d registered successfuly!\n",
bus, slot, func);
@@ -815,6 +805,7 @@ static void xen_pt_unregister_device(PCIDevice *d)
xen_pt_unregister_regions(s);
memory_listener_unregister(&s->memory_listener);
+ memory_listener_unregister(&s->io_listener);
xen_host_pci_device_put(&s->real_device);
}
diff --git a/hw/xen_pt.h b/hw/xen_pt.h
index 112477a..f15e69a 100644
--- a/hw/xen_pt.h
+++ b/hw/xen_pt.h
@@ -209,6 +209,7 @@ struct XenPCIPassthroughState {
MemoryRegion rom;
MemoryListener memory_listener;
+ MemoryListener io_listener;
};
int xen_pt_config_init(XenPCIPassthroughState *s);
OpenPOWER on IntegriCloud