All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API
@ 2012-10-07 12:38 Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 01/23] memory: rename 'exec-obsolete.h' Avi Kivity
                   ` (22 more replies)
  0 siblings, 23 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Most of the work on the memory API focused on memory access targets - the memory regions
and how they are composed into an address space.  This patchset tackles the initator
side of the question - how to originate accesses.

The AddressSpace object, is exported to users and becomes the representation of an
initiator.  Each address space describes the paths from some point in the system
(a device or cpu) to the devices reachable from that initiator.

As an example, the API is used to support PCI_COMMAND_MASTER bit.

Changes from v1:
 - fix typo on commit log for patch 7
 - add address space destruction (resolved FIXME)

Still unresolved:
 - use of structure literal non-extension
 - DEFAULT_OPS vs. if (listener->op) { listener->op(...); }

Two FIXMEs are introduced for the PCI bus master address space, however they're only
exposed by this patch set; the incorrect behaviour is preexisting.  They will be resolved
in a future patchset.

Avi Kivity (23):
  memory: rename 'exec-obsolete.h'
  vhost: use MemoryListener filtering to only monitor RAM address space
  kvm: use separate MemoryListeners for memory and I/O
  xen_pt: use separate MemoryListeners for memory and I/O
  memory: prepare AddressSpace for exporting
  memory: export AddressSpace
  memory: maintain a list of address spaces
  memory: provide defaults for MemoryListener operations
  memory: use new MEMORY_LISTENER_DEFAULT_OPS
  vfio: use new MEMORY_LISTENER_DEFAULT_OPS
  xen_pt: use new MEMORY_LISTENER_DEFAULT_OPS
  kvm: use new MEMORY_LISTENER_DEFAULT_OPS
  xen: use new MEMORY_LISTENER_DEFAULT_OPS
  memory: manage coalesced mmio via a MemoryListener
  memory: move address_space_memory and address_space_io out of memory
    core
  memory: move tcg flush into a tcg memory listener
  memory: use AddressSpace for MemoryListener filtering
  s390: avoid reaching into memory core internals
  memory: per-AddressSpace dispatch
  dma: make dma access its own address space
  memory: add address_space_destroy()
  pci: give each device its own address space
  pci: honor PCI_COMMAND_MASTER

 cputlb.c                             |   6 +-
 cputlb.h                             |   3 +-
 dma-helpers.c                        |  25 ++-
 dma.h                                |  17 +-
 exec-memory.h                        |   7 +-
 exec.c                               | 322 +++++++++++++++--------------------
 hw/Makefile.objs                     |   5 +-
 hw/pci.c                             |  25 ++-
 hw/pci.h                             |   2 +
 hw/spapr_iommu.c                     |   3 +-
 hw/vfio_pci.c                        |  33 +---
 hw/vhost.c                           |   5 +-
 hw/xen_pt.c                          |  49 +++---
 hw/xen_pt.h                          |   1 +
 kvm-all.c                            | 107 +++++-------
 kvm-stub.c                           |  10 --
 kvm.h                                |   2 -
 exec-obsolete.h => memory-internal.h |  31 +++-
 memory.c                             | 172 ++++++++++++-------
 memory.h                             | 134 ++++++++++++++-
 target-s390x/misc_helper.c           |   3 +-
 xen-all.c                            |  45 +----
 22 files changed, 530 insertions(+), 477 deletions(-)
 rename exec-obsolete.h => memory-internal.h (86%)

-- 
1.7.12

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 01/23] memory: rename 'exec-obsolete.h'
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 02/23] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

exec-obsolete.h used to hold pre-memory-API functions that were used from
device code prior to the transition to the memory API.  Now that the
transition is complete, the name no longer describes the file.  The
functions still need to be merged better into the memory core, but there's
no danger of anyone using them.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 cputlb.c                             | 3 +--
 exec.c                               | 3 +--
 exec-obsolete.h => memory-internal.h | 8 ++------
 memory.c                             | 3 +--
 4 files changed, 5 insertions(+), 12 deletions(-)
 rename exec-obsolete.h => memory-internal.h (97%)

diff --git a/cputlb.c b/cputlb.c
index 51b5897..0627f32 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -24,8 +24,7 @@
 
 #include "cputlb.h"
 
-#define WANT_EXEC_OBSOLETE
-#include "exec-obsolete.h"
+#include "memory-internal.h"
 
 //#define DEBUG_TLB
 //#define DEBUG_TLB_CHECK
diff --git a/exec.c b/exec.c
index bb6aa4a..5c703b9 100644
--- a/exec.c
+++ b/exec.c
@@ -59,8 +59,7 @@
 
 #include "cputlb.h"
 
-#define WANT_EXEC_OBSOLETE
-#include "exec-obsolete.h"
+#include "memory-internal.h"
 
 //#define DEBUG_TB_INVALIDATE
 //#define DEBUG_FLUSH
diff --git a/exec-obsolete.h b/memory-internal.h
similarity index 97%
rename from exec-obsolete.h
rename to memory-internal.h
index c099256..655f71f 100644
--- a/exec-obsolete.h
+++ b/memory-internal.h
@@ -16,12 +16,8 @@
  * The functions declared here will be removed soon.
  */
 
-#ifndef EXEC_OBSOLETE_H
-#define EXEC_OBSOLETE_H
-
-#ifndef WANT_EXEC_OBSOLETE
-#error Do not include exec-obsolete.h
-#endif
+#ifndef MEMORY_INTERNAL_H
+#define MEMORY_INTERNAL_H
 
 #ifndef CONFIG_USER_ONLY
 
diff --git a/memory.c b/memory.c
index 4f3ade0..1aeca08 100644
--- a/memory.c
+++ b/memory.c
@@ -20,8 +20,7 @@
 #include "kvm.h"
 #include <assert.h>
 
-#define WANT_EXEC_OBSOLETE
-#include "exec-obsolete.h"
+#include "memory-internal.h"
 
 unsigned memory_region_transaction_depth = 0;
 static bool global_dirty_log = false;
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 02/23] vhost: use MemoryListener filtering to only monitor RAM address space
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 01/23] memory: rename 'exec-obsolete.h' Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 03/23] kvm: use separate MemoryListeners for memory and I/O Avi Kivity
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Instead of checking manually, let the listener filter for us.  This prepares
us for DMA address spaces.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/vhost.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/vhost.c b/hw/vhost.c
index d0ce5aa..100f765 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, get_system_memory());
     hdev->force = force;
     return 0;
 fail:
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 03/23] kvm: use separate MemoryListeners for memory and I/O
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 01/23] memory: rename 'exec-obsolete.h' Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 02/23] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 04/23] xen_pt: " Avi Kivity
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

The construct

   if (address_space == get_system_memory()) {
       // memory thing
   } else {
       // io thing
   }

fails if we have more than two address spaces.  Use a separate listener
for memory and I/O, and utilize MemoryListener's address space filtering to
fix this.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 kvm-all.c | 83 +++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 44 insertions(+), 39 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 92a7137..c69e012 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -755,9 +755,16 @@ static void kvm_log_global_stop(struct MemoryListener *listener)
     assert(r >= 0);
 }
 
-static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
-                                  bool match_data, uint64_t data, int fd)
+static void kvm_log_nop(struct MemoryListener *listener)
 {
+}
+
+static void kvm_mem_ioeventfd_add(MemoryListener *listener,
+                                  MemoryRegionSection *section,
+                                  bool match_data, uint64_t data,
+                                  EventNotifier *e)
+{
+    int fd = event_notifier_get_fd(e);
     int r;
 
     assert(match_data && section->size <= 8);
@@ -769,9 +776,12 @@ static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
     }
 }
 
-static void kvm_mem_ioeventfd_del(MemoryRegionSection *section,
-                                  bool match_data, uint64_t data, int fd)
+static void kvm_mem_ioeventfd_del(MemoryListener *listener,
+                                  MemoryRegionSection *section,
+                                  bool match_data, uint64_t data,
+                                  EventNotifier *e)
 {
+    int fd = event_notifier_get_fd(e);
     int r;
 
     r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
@@ -781,9 +791,12 @@ static void kvm_mem_ioeventfd_del(MemoryRegionSection *section,
     }
 }
 
-static void kvm_io_ioeventfd_add(MemoryRegionSection *section,
-                                 bool match_data, uint64_t data, int fd)
+static void kvm_io_ioeventfd_add(MemoryListener *listener,
+                                 MemoryRegionSection *section,
+                                 bool match_data, uint64_t data,
+                                 EventNotifier *e)
 {
+    int fd = event_notifier_get_fd(e);
     int r;
 
     assert(match_data && section->size == 2);
@@ -795,10 +808,13 @@ static void kvm_io_ioeventfd_add(MemoryRegionSection *section,
     }
 }
 
-static void kvm_io_ioeventfd_del(MemoryRegionSection *section,
-                                 bool match_data, uint64_t data, int fd)
+static void kvm_io_ioeventfd_del(MemoryListener *listener,
+                                 MemoryRegionSection *section,
+                                 bool match_data, uint64_t data,
+                                 EventNotifier *e)
 
 {
+    int fd = event_notifier_get_fd(e);
     int r;
 
     r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
@@ -808,34 +824,6 @@ static void kvm_io_ioeventfd_del(MemoryRegionSection *section,
     }
 }
 
-static void kvm_eventfd_add(MemoryListener *listener,
-                            MemoryRegionSection *section,
-                            bool match_data, uint64_t data,
-                            EventNotifier *e)
-{
-    if (section->address_space == get_system_memory()) {
-        kvm_mem_ioeventfd_add(section, match_data, data,
-			      event_notifier_get_fd(e));
-    } else {
-        kvm_io_ioeventfd_add(section, match_data, data,
-			     event_notifier_get_fd(e));
-    }
-}
-
-static void kvm_eventfd_del(MemoryListener *listener,
-                            MemoryRegionSection *section,
-                            bool match_data, uint64_t data,
-                            EventNotifier *e)
-{
-    if (section->address_space == get_system_memory()) {
-        kvm_mem_ioeventfd_del(section, match_data, data,
-			      event_notifier_get_fd(e));
-    } else {
-        kvm_io_ioeventfd_del(section, match_data, data,
-			     event_notifier_get_fd(e));
-    }
-}
-
 static MemoryListener kvm_memory_listener = {
     .begin = kvm_begin,
     .commit = kvm_commit,
@@ -847,8 +835,24 @@ static void kvm_eventfd_del(MemoryListener *listener,
     .log_sync = kvm_log_sync,
     .log_global_start = kvm_log_global_start,
     .log_global_stop = kvm_log_global_stop,
-    .eventfd_add = kvm_eventfd_add,
-    .eventfd_del = kvm_eventfd_del,
+    .eventfd_add = kvm_mem_ioeventfd_add,
+    .eventfd_del = kvm_mem_ioeventfd_del,
+    .priority = 10,
+};
+
+static MemoryListener kvm_io_listener = {
+    .begin = kvm_begin,
+    .commit = kvm_commit,
+    .region_add = kvm_region_nop,
+    .region_del = kvm_region_nop,
+    .region_nop = kvm_region_nop,
+    .log_start = kvm_region_nop,
+    .log_stop = kvm_region_nop,
+    .log_sync = kvm_region_nop,
+    .log_global_start = kvm_log_nop,
+    .log_global_stop = kvm_log_nop,
+    .eventfd_add = kvm_io_ioeventfd_add,
+    .eventfd_del = kvm_io_ioeventfd_del,
     .priority = 10,
 };
 
@@ -1401,7 +1405,8 @@ int kvm_init(void)
     }
 
     kvm_state = s;
-    memory_listener_register(&kvm_memory_listener, NULL);
+    memory_listener_register(&kvm_memory_listener, get_system_memory());
+    memory_listener_register(&kvm_io_listener, get_system_io());
 
     s->many_ioeventfds = kvm_check_many_ioeventfds();
 
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 04/23] xen_pt: use separate MemoryListeners for memory and I/O
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (2 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 03/23] kvm: use separate MemoryListeners for memory and I/O Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-08 12:18   ` Stefano Stabellini
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 05/23] memory: prepare AddressSpace for exporting Avi Kivity
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Using an unfiltered memory listener will cause regions to be reported
fails multiple times if we have more than two address spaces.  Use a separate
listener for memory and I/O, and utilize MemoryListener's address space
filtering to fix this.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/xen_pt.c | 38 +++++++++++++++++++++++++++++++++++++-
 hw/xen_pt.h |  1 +
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/hw/xen_pt.c b/hw/xen_pt.c
index 307119a..438ad54 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};
@@ -621,6 +622,22 @@ static void xen_pt_region_del(MemoryListener *l, MemoryRegionSection *sec)
     xen_pt_region_update(s, sec, false);
 }
 
+static void xen_pt_io_region_add(MemoryListener *l, MemoryRegionSection *sec)
+{
+    XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
+                                             io_listener);
+
+    xen_pt_region_update(s, sec, true);
+}
+
+static void xen_pt_io_region_del(MemoryListener *l, MemoryRegionSection *sec)
+{
+    XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
+                                             io_listener);
+
+    xen_pt_region_update(s, sec, false);
+}
+
 static void xen_pt_region_nop(MemoryListener *l, MemoryRegionSection *s)
 {
 }
@@ -654,6 +671,22 @@ static void xen_pt_eventfd_fns(MemoryListener *l, MemoryRegionSection *s,
     .priority = 10,
 };
 
+static const MemoryListener xen_pt_io_listener = {
+    .begin = xen_pt_begin,
+    .commit = xen_pt_commit,
+    .region_add = xen_pt_io_region_add,
+    .region_nop = xen_pt_region_nop,
+    .region_del = xen_pt_io_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,
+};
+
 /* init */
 
 static int xen_pt_initfn(PCIDevice *d)
@@ -691,6 +724,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);
@@ -757,7 +791,8 @@ static int xen_pt_initfn(PCIDevice *d)
     }
 
 out:
-    memory_listener_register(&s->memory_listener, NULL);
+    memory_listener_register(&s->memory_listener, get_system_memory());
+    memory_listener_register(&s->io_listener, get_system_io());
     XEN_PT_LOG(d, "Real physical device %02x:%02x.%d registered successfuly!\n",
                bus, slot, func);
 
@@ -812,6 +847,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);
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 05/23] memory: prepare AddressSpace for exporting
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (3 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 04/23] xen_pt: " Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 06/23] memory: export AddressSpace Avi Kivity
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

AddressSpace contains a member, current_map, of type FlatView.  Since we
want to limit the leakage of internal types to public headers, switch to
a pointer to a FlatView.  There is no performance impact as this isn't used
during lookups, only address space reconfigurations.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/memory.c b/memory.c
index 1aeca08..7e9e373 100644
--- a/memory.c
+++ b/memory.c
@@ -222,7 +222,7 @@ struct FlatView {
 /* A system address space - I/O, memory, etc. */
 struct AddressSpace {
     MemoryRegion *root;
-    FlatView current_map;
+    FlatView *current_map;
     int ioeventfd_nb;
     MemoryRegionIoeventfd *ioeventfds;
 };
@@ -631,7 +631,7 @@ static void address_space_update_ioeventfds(AddressSpace *as)
     AddrRange tmp;
     unsigned i;
 
-    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
+    FOR_EACH_FLAT_RANGE(fr, as->current_map) {
         for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
             tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,
                                   int128_sub(fr->addr.start,
@@ -719,13 +719,13 @@ static void address_space_update_topology_pass(AddressSpace *as,
 
 static void address_space_update_topology(AddressSpace *as)
 {
-    FlatView old_view = as->current_map;
+    FlatView old_view = *as->current_map;
     FlatView new_view = generate_memory_topology(as->root);
 
     address_space_update_topology_pass(as, old_view, new_view, false);
     address_space_update_topology_pass(as, old_view, new_view, true);
 
-    as->current_map = new_view;
+    *as->current_map = new_view;
     flatview_destroy(&old_view);
     address_space_update_ioeventfds(as);
 }
@@ -1083,7 +1083,7 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 {
     FlatRange *fr;
 
-    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
+    FOR_EACH_FLAT_RANGE(fr, address_space_memory.current_map) {
         if (fr->mr == mr) {
             MEMORY_LISTENER_UPDATE_REGION(fr, &address_space_memory,
                                           Forward, log_sync);
@@ -1135,7 +1135,7 @@ static void memory_region_update_coalesced_range(MemoryRegion *mr)
     CoalescedMemoryRange *cmr;
     AddrRange tmp;
 
-    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
+    FOR_EACH_FLAT_RANGE(fr, address_space_memory.current_map) {
         if (fr->mr == mr) {
             qemu_unregister_coalesced_mmio(int128_get64(fr->addr.start),
                                            int128_get64(fr->addr.size));
@@ -1399,7 +1399,7 @@ static int cmp_flatrange_addr(const void *addr_, const void *fr_)
 
 static FlatRange *address_space_lookup(AddressSpace *as, AddrRange addr)
 {
-    return bsearch(&addr, as->current_map.ranges, as->current_map.nr,
+    return bsearch(&addr, as->current_map->ranges, as->current_map->nr,
                    sizeof(FlatRange), cmp_flatrange_addr);
 }
 
@@ -1416,7 +1416,7 @@ MemoryRegionSection memory_region_find(MemoryRegion *address_space,
         return ret;
     }
 
-    while (fr > as->current_map.ranges
+    while (fr > as->current_map->ranges
            && addrrange_intersects(fr[-1].addr, range)) {
         --fr;
     }
@@ -1437,7 +1437,7 @@ void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
     AddressSpace *as = memory_region_to_address_space(address_space);
     FlatRange *fr;
 
-    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
+    FOR_EACH_FLAT_RANGE(fr, as->current_map) {
         MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
     }
 }
@@ -1459,6 +1459,10 @@ static void listener_add_address_space(MemoryListener *listener,
 {
     FlatRange *fr;
 
+    if (!as->root) {
+        return;
+    }
+
     if (listener->address_space_filter
         && listener->address_space_filter != as->root) {
         return;
@@ -1467,7 +1471,7 @@ static void listener_add_address_space(MemoryListener *listener,
     if (global_dirty_log) {
         listener->log_global_start(listener);
     }
-    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
+    FOR_EACH_FLAT_RANGE(fr, as->current_map) {
         MemoryRegionSection section = {
             .mr = fr->mr,
             .address_space = as->root,
@@ -1506,18 +1510,23 @@ void memory_listener_unregister(MemoryListener *listener)
     QTAILQ_REMOVE(&memory_listeners, listener, link);
 }
 
-void set_system_memory_map(MemoryRegion *mr)
+static void address_space_init(AddressSpace *as, MemoryRegion *root)
 {
     memory_region_transaction_begin();
-    address_space_memory.root = mr;
+    as->root = root;
+    as->current_map = g_new(FlatView, 1);
+    flatview_init(as->current_map);
     memory_region_transaction_commit();
 }
 
+void set_system_memory_map(MemoryRegion *mr)
+{
+    address_space_init(&address_space_memory, mr);
+}
+
 void set_system_io_map(MemoryRegion *mr)
 {
-    memory_region_transaction_begin();
-    address_space_io.root = mr;
-    memory_region_transaction_commit();
+    address_space_init(&address_space_io, mr);
 }
 
 uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 06/23] memory: export AddressSpace
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (4 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 05/23] memory: prepare AddressSpace for exporting Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 07/23] memory: maintain a list of address spaces Avi Kivity
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

The DMA API will use an AddressSpace to differentiate among different
initiators.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c | 11 +----------
 memory.h | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/memory.c b/memory.c
index 7e9e373..431a867 100644
--- a/memory.c
+++ b/memory.c
@@ -216,17 +216,8 @@ struct FlatView {
     unsigned nr_allocated;
 };
 
-typedef struct AddressSpace AddressSpace;
 typedef struct AddressSpaceOps AddressSpaceOps;
 
-/* A system address space - I/O, memory, etc. */
-struct AddressSpace {
-    MemoryRegion *root;
-    FlatView *current_map;
-    int ioeventfd_nb;
-    MemoryRegionIoeventfd *ioeventfds;
-};
-
 #define FOR_EACH_FLAT_RANGE(var, view)          \
     for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
 
@@ -1510,7 +1501,7 @@ void memory_listener_unregister(MemoryListener *listener)
     QTAILQ_REMOVE(&memory_listeners, listener, link);
 }
 
-static void address_space_init(AddressSpace *as, MemoryRegion *root)
+void address_space_init(AddressSpace *as, MemoryRegion *root)
 {
     memory_region_transaction_begin();
     as->root = root;
diff --git a/memory.h b/memory.h
index 37ce151..a1d75e7 100644
--- a/memory.h
+++ b/memory.h
@@ -157,6 +157,19 @@ struct MemoryRegionPortio {
 
 #define PORTIO_END_OF_LIST() { }
 
+typedef struct AddressSpace AddressSpace;
+
+/**
+ * AddressSpace: describes a mapping of addresses to #MemoryRegion objects
+ */
+struct AddressSpace {
+    /* All fields are private. */
+    MemoryRegion *root;
+    struct FlatView *current_map;
+    int ioeventfd_nb;
+    struct MemoryRegionIoeventfd *ioeventfds;
+};
+
 typedef struct MemoryRegionSection MemoryRegionSection;
 
 /**
@@ -776,6 +789,14 @@ void memory_global_dirty_log_stop(void);
 
 void mtree_info(fprintf_function mon_printf, void *f);
 
+/**
+ * address_space_init: initializes an address space
+ *
+ * @as: an uninitialized #AddressSpace
+ * @root: a #MemoryRegion that routes addesses for the address space
+ */
+void address_space_init(AddressSpace *as, MemoryRegion *root);
+
 #endif
 
 #endif
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 07/23] memory: maintain a list of address spaces
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (5 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 06/23] memory: export AddressSpace Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 08/23] memory: provide defaults for MemoryListener operations Avi Kivity
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Instead of embedding knowledge of the memory and I/O address spaces in the
memory core, maintain a list of all address spaces.  This list will later
be extended dynamically for other bus masters.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c | 75 +++++++++++++++++++++++++++++++++++++++-------------------------
 memory.h |  2 ++
 2 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/memory.c b/memory.c
index 431a867..b58b97c 100644
--- a/memory.c
+++ b/memory.c
@@ -28,6 +28,9 @@
 static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
     = QTAILQ_HEAD_INITIALIZER(memory_listeners);
 
+static QTAILQ_HEAD(, AddressSpace) address_spaces
+    = QTAILQ_HEAD_INITIALIZER(address_spaces);
+
 typedef struct AddrRange AddrRange;
 
 /*
@@ -449,14 +452,15 @@ static void memory_region_iorange_destructor(IORange *iorange)
 
 static AddressSpace *memory_region_to_address_space(MemoryRegion *mr)
 {
+    AddressSpace *as;
+
     while (mr->parent) {
         mr = mr->parent;
     }
-    if (mr == address_space_memory.root) {
-        return &address_space_memory;
-    }
-    if (mr == address_space_io.root) {
-        return &address_space_io;
+    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+        if (mr == as->root) {
+            return as;
+        }
     }
     abort();
 }
@@ -729,16 +733,15 @@ void memory_region_transaction_begin(void)
 
 void memory_region_transaction_commit(void)
 {
+    AddressSpace *as;
+
     assert(memory_region_transaction_depth);
     --memory_region_transaction_depth;
     if (!memory_region_transaction_depth) {
         MEMORY_LISTENER_CALL_GLOBAL(begin, Forward);
 
-        if (address_space_memory.root) {
-            address_space_update_topology(&address_space_memory);
-        }
-        if (address_space_io.root) {
-            address_space_update_topology(&address_space_io);
+        QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+            address_space_update_topology(as);
         }
 
         MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
@@ -1072,12 +1075,14 @@ void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr,
 
 void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 {
+    AddressSpace *as;
     FlatRange *fr;
 
-    FOR_EACH_FLAT_RANGE(fr, address_space_memory.current_map) {
-        if (fr->mr == mr) {
-            MEMORY_LISTENER_UPDATE_REGION(fr, &address_space_memory,
-                                          Forward, log_sync);
+    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+        FOR_EACH_FLAT_RANGE(fr, as->current_map) {
+            if (fr->mr == mr) {
+                MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
+            }
         }
     }
 }
@@ -1120,13 +1125,13 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
     return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
 }
 
-static void memory_region_update_coalesced_range(MemoryRegion *mr)
+static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
 {
     FlatRange *fr;
     CoalescedMemoryRange *cmr;
     AddrRange tmp;
 
-    FOR_EACH_FLAT_RANGE(fr, address_space_memory.current_map) {
+    FOR_EACH_FLAT_RANGE(fr, as->current_map) {
         if (fr->mr == mr) {
             qemu_unregister_coalesced_mmio(int128_get64(fr->addr.start),
                                            int128_get64(fr->addr.size));
@@ -1145,6 +1150,15 @@ static void memory_region_update_coalesced_range(MemoryRegion *mr)
     }
 }
 
+static void memory_region_update_coalesced_range(MemoryRegion *mr)
+{
+    AddressSpace *as;
+
+    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+        memory_region_update_coalesced_range_as(mr, as);
+    }
+}
+
 void memory_region_set_coalescing(MemoryRegion *mr)
 {
     memory_region_clear_coalescing(mr);
@@ -1450,10 +1464,6 @@ static void listener_add_address_space(MemoryListener *listener,
 {
     FlatRange *fr;
 
-    if (!as->root) {
-        return;
-    }
-
     if (listener->address_space_filter
         && listener->address_space_filter != as->root) {
         return;
@@ -1478,6 +1488,7 @@ static void listener_add_address_space(MemoryListener *listener,
 void memory_listener_register(MemoryListener *listener, MemoryRegion *filter)
 {
     MemoryListener *other = NULL;
+    AddressSpace *as;
 
     listener->address_space_filter = filter;
     if (QTAILQ_EMPTY(&memory_listeners)
@@ -1492,8 +1503,10 @@ void memory_listener_register(MemoryListener *listener, MemoryRegion *filter)
         }
         QTAILQ_INSERT_BEFORE(other, listener, link);
     }
-    listener_add_address_space(listener, &address_space_memory);
-    listener_add_address_space(listener, &address_space_io);
+
+    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+        listener_add_address_space(listener, as);
+    }
 }
 
 void memory_listener_unregister(MemoryListener *listener)
@@ -1507,17 +1520,21 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
     as->root = root;
     as->current_map = g_new(FlatView, 1);
     flatview_init(as->current_map);
+    QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
+    as->name = NULL;
     memory_region_transaction_commit();
 }
 
 void set_system_memory_map(MemoryRegion *mr)
 {
     address_space_init(&address_space_memory, mr);
+    address_space_memory.name = "memory";
 }
 
 void set_system_io_map(MemoryRegion *mr)
 {
     address_space_init(&address_space_io, mr);
+    address_space_io.name = "I/O";
 }
 
 uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
@@ -1637,16 +1654,16 @@ void mtree_info(fprintf_function mon_printf, void *f)
 {
     MemoryRegionListHead ml_head;
     MemoryRegionList *ml, *ml2;
+    AddressSpace *as;
 
     QTAILQ_INIT(&ml_head);
 
-    mon_printf(f, "memory\n");
-    mtree_print_mr(mon_printf, f, address_space_memory.root, 0, 0, &ml_head);
-
-    if (address_space_io.root &&
-        !QTAILQ_EMPTY(&address_space_io.root->subregions)) {
-        mon_printf(f, "I/O\n");
-        mtree_print_mr(mon_printf, f, address_space_io.root, 0, 0, &ml_head);
+    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+        if (!as->name) {
+            continue;
+        }
+        mon_printf(f, "%s\n", as->name);
+        mtree_print_mr(mon_printf, f, as->root, 0, 0, &ml_head);
     }
 
     mon_printf(f, "aliases\n");
diff --git a/memory.h b/memory.h
index a1d75e7..46bc5e1 100644
--- a/memory.h
+++ b/memory.h
@@ -164,10 +164,12 @@ typedef struct AddressSpace AddressSpace;
  */
 struct AddressSpace {
     /* All fields are private. */
+    const char *name;
     MemoryRegion *root;
     struct FlatView *current_map;
     int ioeventfd_nb;
     struct MemoryRegionIoeventfd *ioeventfds;
+    QTAILQ_ENTRY(AddressSpace) address_spaces_link;
 };
 
 typedef struct MemoryRegionSection MemoryRegionSection;
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 08/23] memory: provide defaults for MemoryListener operations
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (6 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 07/23] memory: maintain a list of address spaces Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 09/23] memory: use new MEMORY_LISTENER_DEFAULT_OPS Avi Kivity
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Many listeners don't need to respond to all MemoryListener callbacks;
provide suitable defaults instead.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c | 15 +++++++++++++++
 memory.h | 21 +++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/memory.c b/memory.c
index b58b97c..efefcb8 100644
--- a/memory.c
+++ b/memory.c
@@ -1514,6 +1514,21 @@ void memory_listener_unregister(MemoryListener *listener)
     QTAILQ_REMOVE(&memory_listeners, listener, link);
 }
 
+void memory_listener_default_global(MemoryListener *listener)
+{
+}
+
+void memory_listener_default_section(MemoryListener *listener,
+                                     MemoryRegionSection *section)
+{
+}
+
+void memory_listener_default_eventfd(MemoryListener *listener,
+                                     MemoryRegionSection *section,
+                                     bool match_data, uint64_t data, EventNotifier *e)
+{
+}
+
 void address_space_init(AddressSpace *as, MemoryRegion *root)
 {
     memory_region_transaction_begin();
diff --git a/memory.h b/memory.h
index 46bc5e1..0ef95cb 100644
--- a/memory.h
+++ b/memory.h
@@ -223,6 +223,27 @@ struct MemoryListener {
     QTAILQ_ENTRY(MemoryListener) link;
 };
 
+#define MEMORY_LISTENER_DEFAULT_OPS                         \
+    .begin = memory_listener_default_global,                \
+    .commit = memory_listener_default_global,               \
+    .region_add = memory_listener_default_section,          \
+    .region_del = memory_listener_default_section,          \
+    .region_nop = memory_listener_default_section,          \
+    .log_start = memory_listener_default_section,           \
+    .log_stop = memory_listener_default_section,            \
+    .log_sync = memory_listener_default_section,            \
+    .log_global_start = memory_listener_default_global,     \
+    .log_global_stop = memory_listener_default_global,      \
+    .eventfd_add = memory_listener_default_eventfd,         \
+    .eventfd_del = memory_listener_default_eventfd          \
+
+void memory_listener_default_global(MemoryListener *listener);
+void memory_listener_default_section(MemoryListener *listener,
+                                     MemoryRegionSection *section);
+void memory_listener_default_eventfd(MemoryListener *listener,
+                                     MemoryRegionSection *section,
+                                     bool match_data, uint64_t data, EventNotifier *e);
+
 /**
  * memory_region_init: Initialize a memory region
  *
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 09/23] memory: use new MEMORY_LISTENER_DEFAULT_OPS
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (7 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 08/23] memory: provide defaults for MemoryListener operations Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 10/23] vfio: " Avi Kivity
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Removes quite a bit of useless code.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec.c | 98 ++----------------------------------------------------------------
 1 file changed, 2 insertions(+), 96 deletions(-)

diff --git a/exec.c b/exec.c
index 5c703b9..1fd6a10 100644
--- a/exec.c
+++ b/exec.c
@@ -3202,32 +3202,12 @@ static void core_region_add(MemoryListener *listener,
     cpu_register_physical_memory_log(section, section->readonly);
 }
 
-static void core_region_del(MemoryListener *listener,
-                            MemoryRegionSection *section)
-{
-}
-
 static void core_region_nop(MemoryListener *listener,
                             MemoryRegionSection *section)
 {
     cpu_register_physical_memory_log(section, section->readonly);
 }
 
-static void core_log_start(MemoryListener *listener,
-                           MemoryRegionSection *section)
-{
-}
-
-static void core_log_stop(MemoryListener *listener,
-                          MemoryRegionSection *section)
-{
-}
-
-static void core_log_sync(MemoryListener *listener,
-                          MemoryRegionSection *section)
-{
-}
-
 static void core_log_global_start(MemoryListener *listener)
 {
     cpu_physical_memory_set_dirty_tracking(1);
@@ -3238,26 +3218,6 @@ static void core_log_global_stop(MemoryListener *listener)
     cpu_physical_memory_set_dirty_tracking(0);
 }
 
-static void core_eventfd_add(MemoryListener *listener,
-                             MemoryRegionSection *section,
-                             bool match_data, uint64_t data, EventNotifier *e)
-{
-}
-
-static void core_eventfd_del(MemoryListener *listener,
-                             MemoryRegionSection *section,
-                             bool match_data, uint64_t data, EventNotifier *e)
-{
-}
-
-static void io_begin(MemoryListener *listener)
-{
-}
-
-static void io_commit(MemoryListener *listener)
-{
-}
-
 static void io_region_add(MemoryListener *listener,
                           MemoryRegionSection *section)
 {
@@ -3276,75 +3236,21 @@ static void io_region_del(MemoryListener *listener,
     isa_unassign_ioport(section->offset_within_address_space, section->size);
 }
 
-static void io_region_nop(MemoryListener *listener,
-                          MemoryRegionSection *section)
-{
-}
-
-static void io_log_start(MemoryListener *listener,
-                         MemoryRegionSection *section)
-{
-}
-
-static void io_log_stop(MemoryListener *listener,
-                        MemoryRegionSection *section)
-{
-}
-
-static void io_log_sync(MemoryListener *listener,
-                        MemoryRegionSection *section)
-{
-}
-
-static void io_log_global_start(MemoryListener *listener)
-{
-}
-
-static void io_log_global_stop(MemoryListener *listener)
-{
-}
-
-static void io_eventfd_add(MemoryListener *listener,
-                           MemoryRegionSection *section,
-                           bool match_data, uint64_t data, EventNotifier *e)
-{
-}
-
-static void io_eventfd_del(MemoryListener *listener,
-                           MemoryRegionSection *section,
-                           bool match_data, uint64_t data, EventNotifier *e)
-{
-}
-
 static MemoryListener core_memory_listener = {
+    MEMORY_LISTENER_DEFAULT_OPS,
     .begin = core_begin,
     .commit = core_commit,
     .region_add = core_region_add,
-    .region_del = core_region_del,
     .region_nop = core_region_nop,
-    .log_start = core_log_start,
-    .log_stop = core_log_stop,
-    .log_sync = core_log_sync,
     .log_global_start = core_log_global_start,
     .log_global_stop = core_log_global_stop,
-    .eventfd_add = core_eventfd_add,
-    .eventfd_del = core_eventfd_del,
     .priority = 0,
 };
 
 static MemoryListener io_memory_listener = {
-    .begin = io_begin,
-    .commit = io_commit,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .region_add = io_region_add,
     .region_del = io_region_del,
-    .region_nop = io_region_nop,
-    .log_start = io_log_start,
-    .log_stop = io_log_stop,
-    .log_sync = io_log_sync,
-    .log_global_start = io_log_global_start,
-    .log_global_stop = io_log_global_stop,
-    .eventfd_add = io_eventfd_add,
-    .eventfd_del = io_eventfd_del,
     .priority = 0,
 };
 
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 10/23] vfio: use new MEMORY_LISTENER_DEFAULT_OPS
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (8 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 09/23] memory: use new MEMORY_LISTENER_DEFAULT_OPS Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 11/23] xen_pt: " Avi Kivity
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Removes quite a bit of useless code.

Acked-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/vfio_pci.c | 30 +-----------------------------
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index a1eeced..8e49535 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -803,25 +803,6 @@ static int vfio_dma_unmap(VFIOContainer *container,
     return 0;
 }
 
-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);
@@ -913,18 +894,9 @@ static void vfio_listener_region_del(MemoryListener *listener,
 }
 
 static MemoryListener vfio_memory_listener = {
-    .begin = vfio_listener_dummy1,
-    .commit = vfio_listener_dummy1,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .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)
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 11/23] xen_pt: use new MEMORY_LISTENER_DEFAULT_OPS
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (9 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 10/23] vfio: " Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 12/23] kvm: " Avi Kivity
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Removes quite a bit of useless code.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/xen_pt.c | 47 ++---------------------------------------------
 1 file changed, 2 insertions(+), 45 deletions(-)

diff --git a/hw/xen_pt.c b/hw/xen_pt.c
index 438ad54..4dcf46a 100644
--- a/hw/xen_pt.c
+++ b/hw/xen_pt.c
@@ -598,14 +598,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,
@@ -638,52 +630,17 @@ static void xen_pt_io_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_log_fns(MemoryListener *l, MemoryRegionSection *s)
-{
-}
-
-static void xen_pt_log_global_fns(MemoryListener *l)
-{
-}
-
-static void xen_pt_eventfd_fns(MemoryListener *l, MemoryRegionSection *s,
-                               bool match_data, uint64_t data, EventNotifier *n)
-{
-}
-
 static const MemoryListener xen_pt_memory_listener = {
-    .begin = xen_pt_begin,
-    .commit = xen_pt_commit,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .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 = {
-    .begin = xen_pt_begin,
-    .commit = xen_pt_commit,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .region_add = xen_pt_io_region_add,
-    .region_nop = xen_pt_region_nop,
     .region_del = xen_pt_io_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,
 };
 
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 12/23] kvm: use new MEMORY_LISTENER_DEFAULT_OPS
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (10 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 11/23] xen_pt: " Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 13/23] xen: " Avi Kivity
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Removes quite a bit of useless code.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 kvm-all.c | 32 ++------------------------------
 1 file changed, 2 insertions(+), 30 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index c69e012..5e9215d 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -703,14 +703,6 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
     }
 }
 
-static void kvm_begin(MemoryListener *listener)
-{
-}
-
-static void kvm_commit(MemoryListener *listener)
-{
-}
-
 static void kvm_region_add(MemoryListener *listener,
                            MemoryRegionSection *section)
 {
@@ -723,11 +715,6 @@ static void kvm_region_del(MemoryListener *listener,
     kvm_set_phys_mem(section, false);
 }
 
-static void kvm_region_nop(MemoryListener *listener,
-                           MemoryRegionSection *section)
-{
-}
-
 static void kvm_log_sync(MemoryListener *listener,
                          MemoryRegionSection *section)
 {
@@ -755,10 +742,6 @@ static void kvm_log_global_stop(struct MemoryListener *listener)
     assert(r >= 0);
 }
 
-static void kvm_log_nop(struct MemoryListener *listener)
-{
-}
-
 static void kvm_mem_ioeventfd_add(MemoryListener *listener,
                                   MemoryRegionSection *section,
                                   bool match_data, uint64_t data,
@@ -825,11 +808,9 @@ static void kvm_io_ioeventfd_del(MemoryListener *listener,
 }
 
 static MemoryListener kvm_memory_listener = {
-    .begin = kvm_begin,
-    .commit = kvm_commit,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .region_add = kvm_region_add,
     .region_del = kvm_region_del,
-    .region_nop = kvm_region_nop,
     .log_start = kvm_log_start,
     .log_stop = kvm_log_stop,
     .log_sync = kvm_log_sync,
@@ -841,16 +822,7 @@ static void kvm_io_ioeventfd_del(MemoryListener *listener,
 };
 
 static MemoryListener kvm_io_listener = {
-    .begin = kvm_begin,
-    .commit = kvm_commit,
-    .region_add = kvm_region_nop,
-    .region_del = kvm_region_nop,
-    .region_nop = kvm_region_nop,
-    .log_start = kvm_region_nop,
-    .log_stop = kvm_region_nop,
-    .log_sync = kvm_region_nop,
-    .log_global_start = kvm_log_nop,
-    .log_global_stop = kvm_log_nop,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .eventfd_add = kvm_io_ioeventfd_add,
     .eventfd_del = kvm_io_ioeventfd_del,
     .priority = 10,
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 13/23] xen: use new MEMORY_LISTENER_DEFAULT_OPS
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (11 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 12/23] kvm: " Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 14/23] memory: manage coalesced mmio via a MemoryListener Avi Kivity
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Removes quite a bit of useless code.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 xen-all.c | 43 +------------------------------------------
 1 file changed, 1 insertion(+), 42 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index f76b051..823e043 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -452,14 +452,6 @@ static void xen_set_memory(struct MemoryListener *listener,
     }
 }
 
-static void xen_begin(MemoryListener *listener)
-{
-}
-
-static void xen_commit(MemoryListener *listener)
-{
-}
-
 static void xen_region_add(MemoryListener *listener,
                            MemoryRegionSection *section)
 {
@@ -472,11 +464,6 @@ static void xen_region_del(MemoryListener *listener,
     xen_set_memory(listener, section, false);
 }
 
-static void xen_region_nop(MemoryListener *listener,
-                           MemoryRegionSection *section)
-{
-}
-
 static void xen_sync_dirty_bitmap(XenIOState *state,
                                   target_phys_addr_t start_addr,
                                   ram_addr_t size)
@@ -550,41 +537,13 @@ static void xen_log_sync(MemoryListener *listener, MemoryRegionSection *section)
                           section->size);
 }
 
-static void xen_log_global_start(MemoryListener *listener)
-{
-}
-
-static void xen_log_global_stop(MemoryListener *listener)
-{
-}
-
-static void xen_eventfd_add(MemoryListener *listener,
-                            MemoryRegionSection *section,
-                            bool match_data, uint64_t data,
-                            EventNotifier *e)
-{
-}
-
-static void xen_eventfd_del(MemoryListener *listener,
-                            MemoryRegionSection *section,
-                            bool match_data, uint64_t data,
-                            EventNotifier *e)
-{
-}
-
 static MemoryListener xen_memory_listener = {
-    .begin = xen_begin,
-    .commit = xen_commit,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .region_add = xen_region_add,
     .region_del = xen_region_del,
-    .region_nop = xen_region_nop,
     .log_start = xen_log_start,
     .log_stop = xen_log_stop,
     .log_sync = xen_log_sync,
-    .log_global_start = xen_log_global_start,
-    .log_global_stop = xen_log_global_stop,
-    .eventfd_add = xen_eventfd_add,
-    .eventfd_del = xen_eventfd_del,
     .priority = 10,
 };
 
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 14/23] memory: manage coalesced mmio via a MemoryListener
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (12 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 13/23] xen: " Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 15/23] memory: move address_space_memory and address_space_io out of memory core Avi Kivity
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Instead of calling a global function on coalesced mmio changes, which
routes the call to kvm if enabled, add coalesced mmio hooks to
MemoryListener and make kvm use that instead.

The motivation is support for multiple address spaces (which means we
we need to filter the call on the right address space) but the result
is cleaner as well.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec.c     | 13 -------------
 kvm-all.c  | 20 ++++++++++----------
 kvm-stub.c | 10 ----------
 kvm.h      |  2 --
 memory.c   | 24 ++++++++++++++++++++----
 memory.h   | 12 +++++++++++-
 6 files changed, 41 insertions(+), 40 deletions(-)

diff --git a/exec.c b/exec.c
index 1fd6a10..51a32e7 100644
--- a/exec.c
+++ b/exec.c
@@ -2313,19 +2313,6 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
     }
 }
 
-
-void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
-{
-    if (kvm_enabled())
-        kvm_coalesce_mmio_region(addr, size);
-}
-
-void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
-{
-    if (kvm_enabled())
-        kvm_uncoalesce_mmio_region(addr, size);
-}
-
 void qemu_flush_coalesced_mmio_buffer(void)
 {
     if (kvm_enabled())
diff --git a/kvm-all.c b/kvm-all.c
index 5e9215d..25ca202 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -454,9 +454,10 @@ static int kvm_physical_sync_dirty_bitmap(MemoryRegionSection *section)
     return ret;
 }
 
-int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
+static void kvm_coalesce_mmio_region(MemoryListener *listener,
+                                     MemoryRegionSection *secion,
+                                     target_phys_addr_t start, ram_addr_t size)
 {
-    int ret = -ENOSYS;
     KVMState *s = kvm_state;
 
     if (s->coalesced_mmio) {
@@ -466,15 +467,14 @@ int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
         zone.size = size;
         zone.pad = 0;
 
-        ret = kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone);
+        (void)kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone);
     }
-
-    return ret;
 }
 
-int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
+static void kvm_uncoalesce_mmio_region(MemoryListener *listener,
+                                       MemoryRegionSection *secion,
+                                       target_phys_addr_t start, ram_addr_t size)
 {
-    int ret = -ENOSYS;
     KVMState *s = kvm_state;
 
     if (s->coalesced_mmio) {
@@ -484,10 +484,8 @@ int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
         zone.size = size;
         zone.pad = 0;
 
-        ret = kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone);
+        (void)kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone);
     }
-
-    return ret;
 }
 
 int kvm_check_extension(KVMState *s, unsigned int extension)
@@ -818,6 +816,8 @@ static void kvm_io_ioeventfd_del(MemoryListener *listener,
     .log_global_stop = kvm_log_global_stop,
     .eventfd_add = kvm_mem_ioeventfd_add,
     .eventfd_del = kvm_mem_ioeventfd_del,
+    .coalesced_mmio_add = kvm_coalesce_mmio_region,
+    .coalesced_mmio_del = kvm_uncoalesce_mmio_region,
     .priority = 10,
 };
 
diff --git a/kvm-stub.c b/kvm-stub.c
index 3c52eb5..a3455e2 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -29,16 +29,6 @@ int kvm_init_vcpu(CPUArchState *env)
     return -ENOSYS;
 }
 
-int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
-{
-    return -ENOSYS;
-}
-
-int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
-{
-    return -ENOSYS;
-}
-
 int kvm_init(void)
 {
     return -ENOSYS;
diff --git a/kvm.h b/kvm.h
index dea2998..eefcb49 100644
--- a/kvm.h
+++ b/kvm.h
@@ -129,8 +129,6 @@ void *kvm_vmalloc(ram_addr_t size);
 void *kvm_arch_vmalloc(ram_addr_t size);
 void kvm_setup_guest_memory(void *start, size_t size);
 
-int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
-int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
 #endif
 
diff --git a/memory.c b/memory.c
index efefcb8..eb75349 100644
--- a/memory.c
+++ b/memory.c
@@ -1130,11 +1130,19 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
     FlatRange *fr;
     CoalescedMemoryRange *cmr;
     AddrRange tmp;
+    MemoryRegionSection section;
 
     FOR_EACH_FLAT_RANGE(fr, as->current_map) {
         if (fr->mr == mr) {
-            qemu_unregister_coalesced_mmio(int128_get64(fr->addr.start),
-                                           int128_get64(fr->addr.size));
+            section = (MemoryRegionSection) {
+                .address_space = as->root,
+                .offset_within_address_space = int128_get64(fr->addr.start),
+                .size = int128_get64(fr->addr.size),
+            };
+
+            MEMORY_LISTENER_CALL(coalesced_mmio_del, Reverse, &section,
+                                 int128_get64(fr->addr.start),
+                                 int128_get64(fr->addr.size));
             QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
                 tmp = addrrange_shift(cmr->addr,
                                       int128_sub(fr->addr.start,
@@ -1143,8 +1151,9 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
                     continue;
                 }
                 tmp = addrrange_intersection(tmp, fr->addr);
-                qemu_register_coalesced_mmio(int128_get64(tmp.start),
-                                             int128_get64(tmp.size));
+                MEMORY_LISTENER_CALL(coalesced_mmio_add, Forward, &section,
+                                     int128_get64(tmp.start),
+                                     int128_get64(tmp.size));
             }
         }
     }
@@ -1529,6 +1538,13 @@ void memory_listener_default_eventfd(MemoryListener *listener,
 {
 }
 
+void memory_listener_default_coalesced_mmio(MemoryListener *listener,
+                                            MemoryRegionSection *section,
+                                            target_phys_addr_t addr,
+                                            target_phys_addr_t len)
+{
+}
+
 void address_space_init(AddressSpace *as, MemoryRegion *root)
 {
     memory_region_transaction_begin();
diff --git a/memory.h b/memory.h
index 0ef95cb..5f50bce 100644
--- a/memory.h
+++ b/memory.h
@@ -217,6 +217,10 @@ struct MemoryListener {
                         bool match_data, uint64_t data, EventNotifier *e);
     void (*eventfd_del)(MemoryListener *listener, MemoryRegionSection *section,
                         bool match_data, uint64_t data, EventNotifier *e);
+    void (*coalesced_mmio_add)(MemoryListener *listener, MemoryRegionSection *section,
+                               target_phys_addr_t addr, target_phys_addr_t len);
+    void (*coalesced_mmio_del)(MemoryListener *listener, MemoryRegionSection *section,
+                               target_phys_addr_t addr, target_phys_addr_t len);
     /* Lower = earlier (during add), later (during del) */
     unsigned priority;
     MemoryRegion *address_space_filter;
@@ -235,7 +239,9 @@ struct MemoryListener {
     .log_global_start = memory_listener_default_global,     \
     .log_global_stop = memory_listener_default_global,      \
     .eventfd_add = memory_listener_default_eventfd,         \
-    .eventfd_del = memory_listener_default_eventfd          \
+    .eventfd_del = memory_listener_default_eventfd,         \
+    .coalesced_mmio_add = memory_listener_default_coalesced_mmio,  \
+    .coalesced_mmio_del = memory_listener_default_coalesced_mmio   \
 
 void memory_listener_default_global(MemoryListener *listener);
 void memory_listener_default_section(MemoryListener *listener,
@@ -243,6 +249,10 @@ void memory_listener_default_section(MemoryListener *listener,
 void memory_listener_default_eventfd(MemoryListener *listener,
                                      MemoryRegionSection *section,
                                      bool match_data, uint64_t data, EventNotifier *e);
+void memory_listener_default_coalesced_mmio(MemoryListener *listener,
+                                            MemoryRegionSection *section,
+                                            target_phys_addr_t addr,
+                                            target_phys_addr_t len);
 
 /**
  * memory_region_init: Initialize a memory region
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 15/23] memory: move address_space_memory and address_space_io out of memory core
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (13 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 14/23] memory: manage coalesced mmio via a MemoryListener Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 16/23] memory: move tcg flush into a tcg memory listener Avi Kivity
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

With this change, memory.c no longer knows anything about special address
spaces, so it is prepared for AddressSpace based DMA.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-memory.h |  6 ------
 exec.c        |  9 +++++++--
 memory.c      | 16 ----------------
 3 files changed, 7 insertions(+), 24 deletions(-)

diff --git a/exec-memory.h b/exec-memory.h
index 1cd92ee..6707e40 100644
--- a/exec-memory.h
+++ b/exec-memory.h
@@ -33,12 +33,6 @@ MemoryRegion *get_system_memory(void);
  */
 MemoryRegion *get_system_io(void);
 
-/* Set the root memory region.  This region is the system memory map. */
-void set_system_memory_map(MemoryRegion *mr);
-
-/* Set the I/O memory region.  This region is the I/O memory map. */
-void set_system_io_map(MemoryRegion *mr);
-
 #endif
 
 #endif
diff --git a/exec.c b/exec.c
index 51a32e7..e5f26fb 100644
--- a/exec.c
+++ b/exec.c
@@ -116,6 +116,9 @@
 static MemoryRegion *system_memory;
 static MemoryRegion *system_io;
 
+static AddressSpace address_space_io;
+static AddressSpace address_space_memory;
+
 MemoryRegion io_mem_ram, io_mem_rom, io_mem_unassigned, io_mem_notdirty;
 static MemoryRegion io_mem_subpage_ram;
 
@@ -3245,11 +3248,13 @@ static void memory_map_init(void)
 {
     system_memory = g_malloc(sizeof(*system_memory));
     memory_region_init(system_memory, "system", INT64_MAX);
-    set_system_memory_map(system_memory);
+    address_space_init(&address_space_memory, system_memory);
+    address_space_memory.name = "memory";
 
     system_io = g_malloc(sizeof(*system_io));
     memory_region_init(system_io, "io", 65536);
-    set_system_io_map(system_io);
+    address_space_init(&address_space_io, system_io);
+    address_space_io.name = "I/O";
 
     memory_listener_register(&core_memory_listener, system_memory);
     memory_listener_register(&io_memory_listener, system_io);
diff --git a/memory.c b/memory.c
index eb75349..7bc5a32 100644
--- a/memory.c
+++ b/memory.c
@@ -358,8 +358,6 @@ static void access_with_adjusted_size(target_phys_addr_t addr,
     }
 }
 
-static AddressSpace address_space_memory;
-
 static const MemoryRegionPortio *find_portio(MemoryRegion *mr, uint64_t offset,
                                              unsigned width, bool write)
 {
@@ -448,8 +446,6 @@ static void memory_region_iorange_destructor(IORange *iorange)
     .destructor = memory_region_iorange_destructor,
 };
 
-static AddressSpace address_space_io;
-
 static AddressSpace *memory_region_to_address_space(MemoryRegion *mr)
 {
     AddressSpace *as;
@@ -1556,18 +1552,6 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
     memory_region_transaction_commit();
 }
 
-void set_system_memory_map(MemoryRegion *mr)
-{
-    address_space_init(&address_space_memory, mr);
-    address_space_memory.name = "memory";
-}
-
-void set_system_io_map(MemoryRegion *mr)
-{
-    address_space_init(&address_space_io, mr);
-    address_space_io.name = "I/O";
-}
-
 uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
 {
     return memory_region_dispatch_read(mr, addr, size);
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 16/23] memory: move tcg flush into a tcg memory listener
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (14 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 15/23] memory: move address_space_memory and address_space_io out of memory core Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 17/23] memory: use AddressSpace for MemoryListener filtering Avi Kivity
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

We plan to make the core listener listen to all address spaces; this
will cause many more flushes than necessary.  Prepare for that by
moving the flush into a tcg-specific listener.

Later we can avoid registering the listener if tcg is disabled.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index e5f26fb..3c46298 100644
--- a/exec.c
+++ b/exec.c
@@ -3174,7 +3174,7 @@ static void core_begin(MemoryListener *listener)
     phys_section_watch = dummy_section(&io_mem_watch);
 }
 
-static void core_commit(MemoryListener *listener)
+static void tcg_commit(MemoryListener *listener)
 {
     CPUArchState *env;
 
@@ -3229,7 +3229,6 @@ static void io_region_del(MemoryListener *listener,
 static MemoryListener core_memory_listener = {
     MEMORY_LISTENER_DEFAULT_OPS,
     .begin = core_begin,
-    .commit = core_commit,
     .region_add = core_region_add,
     .region_nop = core_region_nop,
     .log_global_start = core_log_global_start,
@@ -3244,6 +3243,11 @@ static void io_region_del(MemoryListener *listener,
     .priority = 0,
 };
 
+static MemoryListener tcg_memory_listener = {
+    MEMORY_LISTENER_DEFAULT_OPS,
+    .commit = tcg_commit,
+};
+
 static void memory_map_init(void)
 {
     system_memory = g_malloc(sizeof(*system_memory));
@@ -3258,6 +3262,7 @@ static void memory_map_init(void)
 
     memory_listener_register(&core_memory_listener, system_memory);
     memory_listener_register(&io_memory_listener, system_io);
+    memory_listener_register(&tcg_memory_listener, system_memory);
 }
 
 MemoryRegion *get_system_memory(void)
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 17/23] memory: use AddressSpace for MemoryListener filtering
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (15 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 16/23] memory: move tcg flush into a tcg memory listener Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 18/23] s390: avoid reaching into memory core internals Avi Kivity
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Using the AddressSpace type reduces confusion, as you can't accidentally
supply the MemoryRegion you're interested in.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-memory.h |  3 +++
 exec.c        | 10 +++++-----
 hw/vfio_pci.c |  3 +--
 hw/vhost.c    |  2 +-
 hw/xen_pt.c   |  4 ++--
 kvm-all.c     |  4 ++--
 memory.c      | 14 +++++++-------
 memory.h      |  6 +++---
 xen-all.c     |  2 +-
 9 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/exec-memory.h b/exec-memory.h
index 6707e40..ac1d07d 100644
--- a/exec-memory.h
+++ b/exec-memory.h
@@ -33,6 +33,9 @@ MemoryRegion *get_system_memory(void);
  */
 MemoryRegion *get_system_io(void);
 
+extern AddressSpace address_space_memory;
+extern AddressSpace address_space_io;
+
 #endif
 
 #endif
diff --git a/exec.c b/exec.c
index 3c46298..7a76efa 100644
--- a/exec.c
+++ b/exec.c
@@ -116,8 +116,8 @@
 static MemoryRegion *system_memory;
 static MemoryRegion *system_io;
 
-static AddressSpace address_space_io;
-static AddressSpace address_space_memory;
+AddressSpace address_space_io;
+AddressSpace address_space_memory;
 
 MemoryRegion io_mem_ram, io_mem_rom, io_mem_unassigned, io_mem_notdirty;
 static MemoryRegion io_mem_subpage_ram;
@@ -3260,9 +3260,9 @@ static void memory_map_init(void)
     address_space_init(&address_space_io, system_io);
     address_space_io.name = "I/O";
 
-    memory_listener_register(&core_memory_listener, system_memory);
-    memory_listener_register(&io_memory_listener, system_io);
-    memory_listener_register(&tcg_memory_listener, system_memory);
+    memory_listener_register(&core_memory_listener, &address_space_memory);
+    memory_listener_register(&io_memory_listener, &address_space_io);
+    memory_listener_register(&tcg_memory_listener, &address_space_memory);
 }
 
 MemoryRegion *get_system_memory(void)
diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 8e49535..dc6c776 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -1406,8 +1406,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 100f765..0b4ac3f 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -792,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, get_system_memory());
+    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 4dcf46a..5a527eb 100644
--- a/hw/xen_pt.c
+++ b/hw/xen_pt.c
@@ -748,8 +748,8 @@ static int xen_pt_initfn(PCIDevice *d)
     }
 
 out:
-    memory_listener_register(&s->memory_listener, get_system_memory());
-    memory_listener_register(&s->io_listener, get_system_io());
+    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);
 
diff --git a/kvm-all.c b/kvm-all.c
index 25ca202..5859d37 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1377,8 +1377,8 @@ int kvm_init(void)
     }
 
     kvm_state = s;
-    memory_listener_register(&kvm_memory_listener, get_system_memory());
-    memory_listener_register(&kvm_io_listener, get_system_io());
+    memory_listener_register(&kvm_memory_listener, &address_space_memory);
+    memory_listener_register(&kvm_io_listener, &address_space_io);
 
     s->many_ioeventfds = kvm_check_many_ioeventfds();
 
diff --git a/memory.c b/memory.c
index 7bc5a32..f829d84 100644
--- a/memory.c
+++ b/memory.c
@@ -141,7 +141,7 @@ static bool memory_listener_match(MemoryListener *listener,
 #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
     MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) {       \
         .mr = (fr)->mr,                                                 \
-        .address_space = (as)->root,                                    \
+        .address_space = (as),                                          \
         .offset_within_region = (fr)->offset_in_region,                 \
         .size = int128_get64((fr)->addr.size),                          \
         .offset_within_address_space = int128_get64((fr)->addr.start),  \
@@ -587,7 +587,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
                                                   fds_new[inew]))) {
             fd = &fds_old[iold];
             section = (MemoryRegionSection) {
-                .address_space = as->root,
+                .address_space = as,
                 .offset_within_address_space = int128_get64(fd->addr.start),
                 .size = int128_get64(fd->addr.size),
             };
@@ -600,7 +600,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
                                                          fds_old[iold]))) {
             fd = &fds_new[inew];
             section = (MemoryRegionSection) {
-                .address_space = as->root,
+                .address_space = as,
                 .offset_within_address_space = int128_get64(fd->addr.start),
                 .size = int128_get64(fd->addr.size),
             };
@@ -1131,7 +1131,7 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
     FOR_EACH_FLAT_RANGE(fr, as->current_map) {
         if (fr->mr == mr) {
             section = (MemoryRegionSection) {
-                .address_space = as->root,
+                .address_space = as,
                 .offset_within_address_space = int128_get64(fr->addr.start),
                 .size = int128_get64(fr->addr.size),
             };
@@ -1470,7 +1470,7 @@ static void listener_add_address_space(MemoryListener *listener,
     FlatRange *fr;
 
     if (listener->address_space_filter
-        && listener->address_space_filter != as->root) {
+        && listener->address_space_filter != as) {
         return;
     }
 
@@ -1480,7 +1480,7 @@ static void listener_add_address_space(MemoryListener *listener,
     FOR_EACH_FLAT_RANGE(fr, as->current_map) {
         MemoryRegionSection section = {
             .mr = fr->mr,
-            .address_space = as->root,
+            .address_space = as,
             .offset_within_region = fr->offset_in_region,
             .size = int128_get64(fr->addr.size),
             .offset_within_address_space = int128_get64(fr->addr.start),
@@ -1490,7 +1490,7 @@ static void listener_add_address_space(MemoryListener *listener,
     }
 }
 
-void memory_listener_register(MemoryListener *listener, MemoryRegion *filter)
+void memory_listener_register(MemoryListener *listener, AddressSpace *filter)
 {
     MemoryListener *other = NULL;
     AddressSpace *as;
diff --git a/memory.h b/memory.h
index 5f50bce..6115f48 100644
--- a/memory.h
+++ b/memory.h
@@ -187,7 +187,7 @@ typedef struct MemoryRegionSection MemoryRegionSection;
  */
 struct MemoryRegionSection {
     MemoryRegion *mr;
-    MemoryRegion *address_space;
+    AddressSpace *address_space;
     target_phys_addr_t offset_within_region;
     uint64_t size;
     target_phys_addr_t offset_within_address_space;
@@ -223,7 +223,7 @@ struct MemoryListener {
                                target_phys_addr_t addr, target_phys_addr_t len);
     /* Lower = earlier (during add), later (during del) */
     unsigned priority;
-    MemoryRegion *address_space_filter;
+    AddressSpace *address_space_filter;
     QTAILQ_ENTRY(MemoryListener) link;
 };
 
@@ -801,7 +801,7 @@ void memory_region_transaction_commit(void);
  * @listener: an object containing the callbacks to be called
  * @filter: if non-%NULL, only regions in this address space will be observed
  */
-void memory_listener_register(MemoryListener *listener, MemoryRegion *filter);
+void memory_listener_register(MemoryListener *listener, AddressSpace *filter);
 
 /**
  * memory_listener_unregister: undo the effect of memory_listener_register()
diff --git a/xen-all.c b/xen-all.c
index 823e043..85f799b 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -1117,7 +1117,7 @@ int xen_hvm_init(void)
 
     state->memory_listener = xen_memory_listener;
     QLIST_INIT(&state->physmap);
-    memory_listener_register(&state->memory_listener, get_system_memory());
+    memory_listener_register(&state->memory_listener, &address_space_memory);
     state->log_for_dirtybit = NULL;
 
     /* Initialize backend core & drivers */
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 18/23] s390: avoid reaching into memory core internals
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (16 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 17/23] memory: use AddressSpace for MemoryListener filtering Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 19/23] memory: per-AddressSpace dispatch Avi Kivity
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

use cpu_physical_memory_is_io() instead.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-s390x/misc_helper.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index e9b3cae..fdccd58 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -20,7 +20,6 @@
 
 #include "cpu.h"
 #include "memory.h"
-#include "cputlb.h"
 #include "host-utils.h"
 #include "helper.h"
 #include <string.h>
@@ -81,7 +80,7 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
 #endif
 
     /* basic checks */
-    if (!memory_region_is_ram(phys_page_find(sccb >> TARGET_PAGE_BITS)->mr)) {
+    if (cpu_physical_memory_is_io(sccb)) {
         return -PGM_ADDRESSING;
     }
     if (sccb & ~0x7ffffff8ul) {
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 19/23] memory: per-AddressSpace dispatch
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (17 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 18/23] s390: avoid reaching into memory core internals Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 20/23] dma: make dma access its own address space Avi Kivity
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Currently we use a global radix tree to dispatch memory access.  This only
works with a single address space; to support multiple address spaces we
make the radix tree a member of AddressSpace (via an intermediate structure
AddressSpaceDispatch to avoid exposing too many internals).

A side effect is that address_space_io also gains a dispatch table.  When
we remove all the pre-memory-API I/O registrations, we can use that for
dispatching I/O and get rid of the original I/O dispatch.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 cputlb.c          |   3 +-
 cputlb.h          |   3 +-
 exec.c            | 176 +++++++++++++++++++++++++++++++++---------------------
 memory-internal.h |  22 ++++++-
 memory.c          |   1 +
 memory.h          |  62 +++++++++++++++++++
 6 files changed, 196 insertions(+), 71 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index 0627f32..9027557 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -21,6 +21,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "memory.h"
+#include "exec-memory.h"
 
 #include "cputlb.h"
 
@@ -251,7 +252,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
     if (size != TARGET_PAGE_SIZE) {
         tlb_add_large_page(env, vaddr, size);
     }
-    section = phys_page_find(paddr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, paddr >> TARGET_PAGE_BITS);
 #if defined(DEBUG_TLB)
     printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
            " prot=%x idx=%d pd=0x%08lx\n",
diff --git a/cputlb.h b/cputlb.h
index 2dc2c96..d537b77 100644
--- a/cputlb.h
+++ b/cputlb.h
@@ -26,7 +26,8 @@ void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
                              target_ulong vaddr);
 void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
                            uintptr_t length);
-MemoryRegionSection *phys_page_find(target_phys_addr_t index);
+MemoryRegionSection *phys_page_find(struct AddressSpaceDispatch *d,
+                                    target_phys_addr_t index);
 void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
 void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
 extern int tlb_flush_count;
diff --git a/exec.c b/exec.c
index 7a76efa..42f9ad1 100644
--- a/exec.c
+++ b/exec.c
@@ -187,7 +187,6 @@
 static void *l1_map[V_L1_SIZE];
 
 #if !defined(CONFIG_USER_ONLY)
-typedef struct PhysPageEntry PhysPageEntry;
 
 static MemoryRegionSection *phys_sections;
 static unsigned phys_sections_nb, phys_sections_nb_alloc;
@@ -196,22 +195,12 @@
 static uint16_t phys_section_rom;
 static uint16_t phys_section_watch;
 
-struct PhysPageEntry {
-    uint16_t is_leaf : 1;
-     /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
-    uint16_t ptr : 15;
-};
-
 /* Simple allocator for PhysPageEntry nodes */
 static PhysPageEntry (*phys_map_nodes)[L2_SIZE];
 static unsigned phys_map_nodes_nb, phys_map_nodes_nb_alloc;
 
 #define PHYS_MAP_NODE_NIL (((uint16_t)~0) >> 1)
 
-/* This is a multi-level map on the physical address space.
-   The bottom level has pointers to MemoryRegionSections.  */
-static PhysPageEntry phys_map = { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
-
 static void io_mem_init(void);
 static void memory_map_init(void);
 
@@ -459,18 +448,19 @@ static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t *index,
     }
 }
 
-static void phys_page_set(target_phys_addr_t index, target_phys_addr_t nb,
+static void phys_page_set(AddressSpaceDispatch *d,
+                          target_phys_addr_t index, target_phys_addr_t nb,
                           uint16_t leaf)
 {
     /* Wildly overreserve - it doesn't matter much. */
     phys_map_node_reserve(3 * P_L2_LEVELS);
 
-    phys_page_set_level(&phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
+    phys_page_set_level(&d->phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
 }
 
-MemoryRegionSection *phys_page_find(target_phys_addr_t index)
+MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, target_phys_addr_t index)
 {
-    PhysPageEntry lp = phys_map;
+    PhysPageEntry lp = d->phys_map;
     PhysPageEntry *p;
     int i;
     uint16_t s_index = phys_section_unassigned;
@@ -1472,7 +1462,7 @@ void tb_invalidate_phys_addr(target_phys_addr_t addr)
     ram_addr_t ram_addr;
     MemoryRegionSection *section;
 
-    section = phys_page_find(addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
     if (!(memory_region_is_ram(section->mr)
           || (section->mr->rom_device && section->mr->readable))) {
         return;
@@ -2218,9 +2208,9 @@ static void destroy_l2_mapping(PhysPageEntry *lp, unsigned level)
     lp->ptr = PHYS_MAP_NODE_NIL;
 }
 
-static void destroy_all_mappings(void)
+static void destroy_all_mappings(AddressSpaceDispatch *d)
 {
-    destroy_l2_mapping(&phys_map, P_L2_LEVELS - 1);
+    destroy_l2_mapping(&d->phys_map, P_L2_LEVELS - 1);
     phys_map_nodes_reset();
 }
 
@@ -2240,12 +2230,12 @@ static void phys_sections_clear(void)
     phys_sections_nb = 0;
 }
 
-static void register_subpage(MemoryRegionSection *section)
+static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section)
 {
     subpage_t *subpage;
     target_phys_addr_t base = section->offset_within_address_space
         & TARGET_PAGE_MASK;
-    MemoryRegionSection *existing = phys_page_find(base >> TARGET_PAGE_BITS);
+    MemoryRegionSection *existing = phys_page_find(d, base >> TARGET_PAGE_BITS);
     MemoryRegionSection subsection = {
         .offset_within_address_space = base,
         .size = TARGET_PAGE_SIZE,
@@ -2257,7 +2247,7 @@ static void register_subpage(MemoryRegionSection *section)
     if (!(existing->mr->subpage)) {
         subpage = subpage_init(base);
         subsection.mr = &subpage->iomem;
-        phys_page_set(base >> TARGET_PAGE_BITS, 1,
+        phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
                       phys_section_add(&subsection));
     } else {
         subpage = container_of(existing->mr, subpage_t, iomem);
@@ -2268,7 +2258,7 @@ static void register_subpage(MemoryRegionSection *section)
 }
 
 
-static void register_multipage(MemoryRegionSection *section)
+static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *section)
 {
     target_phys_addr_t start_addr = section->offset_within_address_space;
     ram_addr_t size = section->size;
@@ -2278,13 +2268,13 @@ static void register_multipage(MemoryRegionSection *section)
     assert(size);
 
     addr = start_addr;
-    phys_page_set(addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS,
+    phys_page_set(d, addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS,
                   section_index);
 }
 
-void cpu_register_physical_memory_log(MemoryRegionSection *section,
-                                      bool readonly)
+static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
 {
+    AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
     MemoryRegionSection now = *section, remain = *section;
 
     if ((now.offset_within_address_space & ~TARGET_PAGE_MASK)
@@ -2292,7 +2282,7 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
         now.size = MIN(TARGET_PAGE_ALIGN(now.offset_within_address_space)
                        - now.offset_within_address_space,
                        now.size);
-        register_subpage(&now);
+        register_subpage(d, &now);
         remain.size -= now.size;
         remain.offset_within_address_space += now.size;
         remain.offset_within_region += now.size;
@@ -2301,10 +2291,10 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
         now = remain;
         if (remain.offset_within_region & ~TARGET_PAGE_MASK) {
             now.size = TARGET_PAGE_SIZE;
-            register_subpage(&now);
+            register_subpage(d, &now);
         } else {
             now.size &= TARGET_PAGE_MASK;
-            register_multipage(&now);
+            register_multipage(d, &now);
         }
         remain.size -= now.size;
         remain.offset_within_address_space += now.size;
@@ -2312,7 +2302,7 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
     }
     now = remain;
     if (now.size) {
-        register_subpage(&now);
+        register_subpage(d, &now);
     }
 }
 
@@ -3163,11 +3153,17 @@ static void io_mem_init(void)
                           "watch", UINT64_MAX);
 }
 
+static void mem_begin(MemoryListener *listener)
+{
+    AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
+
+    destroy_all_mappings(d);
+    d->phys_map.ptr = PHYS_MAP_NODE_NIL;
+}
+
 static void core_begin(MemoryListener *listener)
 {
-    destroy_all_mappings();
     phys_sections_clear();
-    phys_map.ptr = PHYS_MAP_NODE_NIL;
     phys_section_unassigned = dummy_section(&io_mem_unassigned);
     phys_section_notdirty = dummy_section(&io_mem_notdirty);
     phys_section_rom = dummy_section(&io_mem_rom);
@@ -3186,18 +3182,6 @@ static void tcg_commit(MemoryListener *listener)
     }
 }
 
-static void core_region_add(MemoryListener *listener,
-                            MemoryRegionSection *section)
-{
-    cpu_register_physical_memory_log(section, section->readonly);
-}
-
-static void core_region_nop(MemoryListener *listener,
-                            MemoryRegionSection *section)
-{
-    cpu_register_physical_memory_log(section, section->readonly);
-}
-
 static void core_log_global_start(MemoryListener *listener)
 {
     cpu_physical_memory_set_dirty_tracking(1);
@@ -3229,11 +3213,9 @@ static void io_region_del(MemoryListener *listener,
 static MemoryListener core_memory_listener = {
     MEMORY_LISTENER_DEFAULT_OPS,
     .begin = core_begin,
-    .region_add = core_region_add,
-    .region_nop = core_region_nop,
     .log_global_start = core_log_global_start,
     .log_global_stop = core_log_global_stop,
-    .priority = 0,
+    .priority = 1,
 };
 
 static MemoryListener io_memory_listener = {
@@ -3248,6 +3230,22 @@ static void io_region_del(MemoryListener *listener,
     .commit = tcg_commit,
 };
 
+void address_space_init_dispatch(AddressSpace *as)
+{
+    AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);
+
+    d->phys_map  = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
+    d->listener = (MemoryListener) {
+        MEMORY_LISTENER_DEFAULT_OPS,
+        .begin = mem_begin,
+        .region_add = mem_add,
+        .region_nop = mem_add,
+        .priority = 0,
+    };
+    as->dispatch = d;
+    memory_listener_register(&d->listener, as);
+}
+
 static void memory_map_init(void)
 {
     system_memory = g_malloc(sizeof(*system_memory));
@@ -3319,9 +3317,11 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
 }
 
 #else
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
-                            int len, int is_write)
+
+void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf,
+                      int len, bool is_write)
 {
+    AddressSpaceDispatch *d = as->dispatch;
     int l;
     uint8_t *ptr;
     uint32_t val;
@@ -3333,7 +3333,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
         l = (page + TARGET_PAGE_SIZE) - addr;
         if (l > len)
             l = len;
-        section = phys_page_find(page >> TARGET_PAGE_BITS);
+        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
 
         if (is_write) {
             if (!memory_region_is_ram(section->mr)) {
@@ -3410,10 +3410,36 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
     }
 }
 
+void address_space_write(AddressSpace *as, target_phys_addr_t addr,
+                         const uint8_t *buf, int len)
+{
+    address_space_rw(as, addr, (uint8_t *)buf, len, true);
+}
+
+/**
+ * address_space_read: read from an address space.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ */
+void address_space_read(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, int len)
+{
+    address_space_rw(as, addr, buf, len, false);
+}
+
+
+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
+                            int len, int is_write)
+{
+    return address_space_rw(&address_space_memory, addr, buf, len, is_write);
+}
+
 /* used for ROM loading : can write in RAM and ROM */
 void cpu_physical_memory_write_rom(target_phys_addr_t addr,
                                    const uint8_t *buf, int len)
 {
+    AddressSpaceDispatch *d = address_space_memory.dispatch;
     int l;
     uint8_t *ptr;
     target_phys_addr_t page;
@@ -3424,7 +3450,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
         l = (page + TARGET_PAGE_SIZE) - addr;
         if (l > len)
             l = len;
-        section = phys_page_find(page >> TARGET_PAGE_BITS);
+        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
 
         if (!(memory_region_is_ram(section->mr) ||
               memory_region_is_romd(section->mr))) {
@@ -3504,10 +3530,12 @@ static void cpu_notify_map_clients(void)
  * Use cpu_register_map_client() to know when retrying the map operation is
  * likely to succeed.
  */
-void *cpu_physical_memory_map(target_phys_addr_t addr,
-                              target_phys_addr_t *plen,
-                              int is_write)
+void *address_space_map(AddressSpace *as,
+                        target_phys_addr_t addr,
+                        target_phys_addr_t *plen,
+                        bool is_write)
 {
+    AddressSpaceDispatch *d = as->dispatch;
     target_phys_addr_t len = *plen;
     target_phys_addr_t todo = 0;
     int l;
@@ -3522,7 +3550,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
         l = (page + TARGET_PAGE_SIZE) - addr;
         if (l > len)
             l = len;
-        section = phys_page_find(page >> TARGET_PAGE_BITS);
+        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
 
         if (!(memory_region_is_ram(section->mr) && !section->readonly)) {
             if (todo || bounce.buffer) {
@@ -3532,7 +3560,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
             bounce.addr = addr;
             bounce.len = l;
             if (!is_write) {
-                cpu_physical_memory_read(addr, bounce.buffer, l);
+                address_space_read(as, addr, bounce.buffer, l);
             }
 
             *plen = l;
@@ -3553,12 +3581,12 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
     return ret;
 }
 
-/* Unmaps a memory region previously mapped by cpu_physical_memory_map().
+/* Unmaps a memory region previously mapped by address_space_map().
  * Will also mark the memory as dirty if is_write == 1.  access_len gives
  * the amount of memory that was actually read or written by the caller.
  */
-void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
-                               int is_write, target_phys_addr_t access_len)
+void address_space_unmap(AddressSpace *as, void *buffer, target_phys_addr_t len,
+                         int is_write, target_phys_addr_t access_len)
 {
     if (buffer != bounce.buffer) {
         if (is_write) {
@@ -3585,13 +3613,26 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
         return;
     }
     if (is_write) {
-        cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len);
+        address_space_write(as, bounce.addr, bounce.buffer, access_len);
     }
     qemu_vfree(bounce.buffer);
     bounce.buffer = NULL;
     cpu_notify_map_clients();
 }
 
+void *cpu_physical_memory_map(target_phys_addr_t addr,
+                              target_phys_addr_t *plen,
+                              int is_write)
+{
+    return address_space_map(&address_space_memory, addr, plen, is_write);
+}
+
+void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
+                               int is_write, target_phys_addr_t access_len)
+{
+    return address_space_unmap(&address_space_memory, buffer, len, is_write, access_len);
+}
+
 /* warning: addr must be aligned */
 static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
                                          enum device_endian endian)
@@ -3600,7 +3641,7 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
     uint32_t val;
     MemoryRegionSection *section;
 
-    section = phys_page_find(addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
 
     if (!(memory_region_is_ram(section->mr) ||
           memory_region_is_romd(section->mr))) {
@@ -3659,7 +3700,7 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
     uint64_t val;
     MemoryRegionSection *section;
 
-    section = phys_page_find(addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
 
     if (!(memory_region_is_ram(section->mr) ||
           memory_region_is_romd(section->mr))) {
@@ -3726,7 +3767,7 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
     uint64_t val;
     MemoryRegionSection *section;
 
-    section = phys_page_find(addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
 
     if (!(memory_region_is_ram(section->mr) ||
           memory_region_is_romd(section->mr))) {
@@ -3785,7 +3826,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
     uint8_t *ptr;
     MemoryRegionSection *section;
 
-    section = phys_page_find(addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
 
     if (!memory_region_is_ram(section->mr) || section->readonly) {
         addr = memory_region_section_addr(section, addr);
@@ -3817,7 +3858,7 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
     uint8_t *ptr;
     MemoryRegionSection *section;
 
-    section = phys_page_find(addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
 
     if (!memory_region_is_ram(section->mr) || section->readonly) {
         addr = memory_region_section_addr(section, addr);
@@ -3846,7 +3887,7 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
     uint8_t *ptr;
     MemoryRegionSection *section;
 
-    section = phys_page_find(addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
 
     if (!memory_region_is_ram(section->mr) || section->readonly) {
         addr = memory_region_section_addr(section, addr);
@@ -3919,7 +3960,7 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
     uint8_t *ptr;
     MemoryRegionSection *section;
 
-    section = phys_page_find(addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
 
     if (!memory_region_is_ram(section->mr) || section->readonly) {
         addr = memory_region_section_addr(section, addr);
@@ -4161,7 +4202,8 @@ bool cpu_physical_memory_is_io(target_phys_addr_t phys_addr)
 {
     MemoryRegionSection *section;
 
-    section = phys_page_find(phys_addr >> TARGET_PAGE_BITS);
+    section = phys_page_find(address_space_memory.dispatch,
+                             phys_addr >> TARGET_PAGE_BITS);
 
     return !(memory_region_is_ram(section->mr) ||
              memory_region_is_romd(section->mr));
diff --git a/memory-internal.h b/memory-internal.h
index 655f71f..a9d914e 100644
--- a/memory-internal.h
+++ b/memory-internal.h
@@ -21,6 +21,26 @@
 
 #ifndef CONFIG_USER_ONLY
 
+typedef struct PhysPageEntry PhysPageEntry;
+
+struct PhysPageEntry {
+    uint16_t is_leaf : 1;
+     /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
+    uint16_t ptr : 15;
+};
+
+typedef struct AddressSpaceDispatch AddressSpaceDispatch;
+
+struct AddressSpaceDispatch {
+    /* This is a multi-level map on the physical address space.
+     * The bottom level has pointers to MemoryRegionSections.
+     */
+    PhysPageEntry phys_map;
+    MemoryListener listener;
+};
+
+void address_space_init_dispatch(AddressSpace *as);
+
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                    MemoryRegion *mr);
 ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
@@ -29,8 +49,6 @@ void qemu_ram_free_from_ptr(ram_addr_t addr);
 
 struct MemoryRegion;
 struct MemoryRegionSection;
-void cpu_register_physical_memory_log(struct MemoryRegionSection *section,
-                                      bool readonly);
 
 void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
 void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
diff --git a/memory.c b/memory.c
index f829d84..28a79ae 100644
--- a/memory.c
+++ b/memory.c
@@ -1550,6 +1550,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
     QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
     as->name = NULL;
     memory_region_transaction_commit();
+    address_space_init_dispatch(as);
 }
 
 uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
diff --git a/memory.h b/memory.h
index 6115f48..84f7439 100644
--- a/memory.h
+++ b/memory.h
@@ -169,6 +169,7 @@ struct AddressSpace {
     struct FlatView *current_map;
     int ioeventfd_nb;
     struct MemoryRegionIoeventfd *ioeventfds;
+    struct AddressSpaceDispatch *dispatch;
     QTAILQ_ENTRY(AddressSpace) address_spaces_link;
 };
 
@@ -830,6 +831,67 @@ void mtree_info(fprintf_function mon_printf, void *f);
  */
 void address_space_init(AddressSpace *as, MemoryRegion *root);
 
+/**
+ * address_space_rw: read from or write to an address space.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @is_write: indicates the transfer direction
+ */
+void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf,
+                      int len, bool is_write);
+
+/**
+ * address_space_write: write to address space.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ */
+void address_space_write(AddressSpace *as, target_phys_addr_t addr,
+                         const uint8_t *buf, int len);
+
+/**
+ * address_space_read: read from an address space.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ */
+void address_space_read(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, int len);
+
+/* address_space_map: map a physical memory region into a host virtual address
+ *
+ * May map a subset of the requested range, given by and returned in @plen.
+ * May return %NULL if resources needed to perform the mapping are exhausted.
+ * Use only for reads OR writes - not for read-modify-write operations.
+ * Use cpu_register_map_client() to know when retrying the map operation is
+ * likely to succeed.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @plen: pointer to length of buffer; updated on return
+ * @is_write: indicates the transfer direction
+ */
+void *address_space_map(AddressSpace *as, target_phys_addr_t addr,
+                        target_phys_addr_t *plen, bool is_write);
+
+/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
+ *
+ * Will also mark the memory as dirty if @is_write == %true.  @access_len gives
+ * the amount of memory that was actually read or written by the caller.
+ *
+ * @as: #AddressSpace used
+ * @addr: address within that address space
+ * @len: buffer length as returned by address_space_map()
+ * @access_len: amount of data actually transferred
+ * @is_write: indicates the transfer direction
+ */
+void address_space_unmap(AddressSpace *as, void *buffer, target_phys_addr_t len,
+                         int is_write, target_phys_addr_t access_len);
+
+
 #endif
 
 #endif
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 20/23] dma: make dma access its own address space
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (18 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 19/23] memory: per-AddressSpace dispatch Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 21/23] memory: add address_space_destroy() Avi Kivity
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Instead of accessing the cpu address space, use an address space
configured by the caller.

Eventually all dma functionality will be folded into AddressSpace,
but we have to start from something.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 dma-helpers.c    | 25 ++++++++++++-------------
 dma.h            | 17 ++++++++---------
 hw/Makefile.objs |  5 +++--
 hw/spapr_iommu.c |  3 ++-
 4 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/dma-helpers.c b/dma-helpers.c
index 433d8b2..3f09dcb 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -14,7 +14,8 @@
 
 /* #define DEBUG_IOMMU */
 
-static void do_dma_memory_set(dma_addr_t addr, uint8_t c, dma_addr_t len)
+static void do_dma_memory_set(AddressSpace *as,
+                              dma_addr_t addr, uint8_t c, dma_addr_t len)
 {
 #define FILLBUF_SIZE 512
     uint8_t fillbuf[FILLBUF_SIZE];
@@ -23,7 +24,7 @@ static void do_dma_memory_set(dma_addr_t addr, uint8_t c, dma_addr_t len)
     memset(fillbuf, c, FILLBUF_SIZE);
     while (len > 0) {
         l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE;
-        cpu_physical_memory_rw(addr, fillbuf, l, true);
+        address_space_rw(as, addr, fillbuf, l, true);
         len -= l;
         addr += l;
     }
@@ -36,7 +37,7 @@ int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len)
     if (dma_has_iommu(dma)) {
         return iommu_dma_memory_set(dma, addr, c, len);
     }
-    do_dma_memory_set(addr, c, len);
+    do_dma_memory_set(dma->as, addr, c, len);
 
     return 0;
 }
@@ -332,8 +333,7 @@ int iommu_dma_memory_rw(DMAContext *dma, dma_addr_t addr,
             plen = len;
         }
 
-        cpu_physical_memory_rw(paddr, buf, plen,
-                               dir == DMA_DIRECTION_FROM_DEVICE);
+        address_space_rw(dma->as, paddr, buf, plen, dir == DMA_DIRECTION_FROM_DEVICE);
 
         len -= plen;
         addr += plen;
@@ -366,7 +366,7 @@ int iommu_dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c,
             plen = len;
         }
 
-        do_dma_memory_set(paddr, c, plen);
+        do_dma_memory_set(dma->as, paddr, c, plen);
 
         len -= plen;
         addr += plen;
@@ -375,13 +375,14 @@ int iommu_dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c,
     return 0;
 }
 
-void dma_context_init(DMAContext *dma, DMATranslateFunc translate,
+void dma_context_init(DMAContext *dma, AddressSpace *as, DMATranslateFunc translate,
                       DMAMapFunc map, DMAUnmapFunc unmap)
 {
 #ifdef DEBUG_IOMMU
     fprintf(stderr, "dma_context_init(%p, %p, %p, %p)\n",
             dma, translate, map, unmap);
 #endif
+    dma->as = as;
     dma->translate = translate;
     dma->map = map;
     dma->unmap = unmap;
@@ -407,14 +408,13 @@ void *iommu_dma_memory_map(DMAContext *dma, dma_addr_t addr, dma_addr_t *len,
     /*
      * If this is true, the virtual region is contiguous,
      * but the translated physical region isn't. We just
-     * clamp *len, much like cpu_physical_memory_map() does.
+     * clamp *len, much like address_space_map() does.
      */
     if (plen < *len) {
         *len = plen;
     }
 
-    buf = cpu_physical_memory_map(paddr, &plen,
-                                  dir == DMA_DIRECTION_FROM_DEVICE);
+    buf = address_space_map(dma->as, paddr, &plen, dir == DMA_DIRECTION_FROM_DEVICE);
     *len = plen;
 
     return buf;
@@ -428,8 +428,7 @@ void iommu_dma_memory_unmap(DMAContext *dma, void *buffer, dma_addr_t len,
         return;
     }
 
-    cpu_physical_memory_unmap(buffer, len,
-                              dir == DMA_DIRECTION_FROM_DEVICE,
-                              access_len);
+    address_space_unmap(dma->as, buffer, len, dir == DMA_DIRECTION_FROM_DEVICE,
+                        access_len);
 
 }
diff --git a/dma.h b/dma.h
index f35c4b6..94cf806 100644
--- a/dma.h
+++ b/dma.h
@@ -11,6 +11,7 @@
 #define DMA_H
 
 #include <stdio.h>
+#include "memory.h"
 #include "hw/hw.h"
 #include "block.h"
 #include "kvm.h"
@@ -61,6 +62,7 @@ typedef void DMAUnmapFunc(DMAContext *dma,
                           dma_addr_t access_len);
 
 struct DMAContext {
+    AddressSpace *as;
     DMATranslateFunc *translate;
     DMAMapFunc *map;
     DMAUnmapFunc *unmap;
@@ -93,7 +95,7 @@ static inline void dma_barrier(DMAContext *dma, DMADirection dir)
 
 static inline bool dma_has_iommu(DMAContext *dma)
 {
-    return !!dma;
+    return dma && dma->translate;
 }
 
 /* Checks that the given range of addresses is valid for DMA.  This is
@@ -120,8 +122,7 @@ static inline int dma_memory_rw_relaxed(DMAContext *dma, dma_addr_t addr,
 {
     if (!dma_has_iommu(dma)) {
         /* Fast-path for no IOMMU */
-        cpu_physical_memory_rw(addr, buf, len,
-                               dir == DMA_DIRECTION_FROM_DEVICE);
+        address_space_rw(dma->as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
         return 0;
     } else {
         return iommu_dma_memory_rw(dma, addr, buf, len, dir);
@@ -179,8 +180,7 @@ static inline void *dma_memory_map(DMAContext *dma,
         target_phys_addr_t xlen = *len;
         void *p;
 
-        p = cpu_physical_memory_map(addr, &xlen,
-                                    dir == DMA_DIRECTION_FROM_DEVICE);
+        p = address_space_map(dma->as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
         *len = xlen;
         return p;
     } else {
@@ -196,9 +196,8 @@ static inline void dma_memory_unmap(DMAContext *dma,
                                     DMADirection dir, dma_addr_t access_len)
 {
     if (!dma_has_iommu(dma)) {
-        cpu_physical_memory_unmap(buffer, (target_phys_addr_t)len,
-                                  dir == DMA_DIRECTION_FROM_DEVICE,
-                                  access_len);
+        address_space_unmap(dma->as, buffer, (target_phys_addr_t)len,
+                            dir == DMA_DIRECTION_FROM_DEVICE, access_len);
     } else {
         iommu_dma_memory_unmap(dma, buffer, len, dir, access_len);
     }
@@ -242,7 +241,7 @@ DEFINE_LDST_DMA(q, q, 64, be);
 
 #undef DEFINE_LDST_DMA
 
-void dma_context_init(DMAContext *dma, DMATranslateFunc translate,
+void dma_context_init(DMAContext *dma, AddressSpace *as, DMATranslateFunc translate,
                       DMAMapFunc map, DMAUnmapFunc unmap);
 
 struct ScatterGatherEntry {
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index ecdbe44..9e4ec6e 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -169,8 +169,9 @@ common-obj-$(CONFIG_MAX111X) += max111x.o
 common-obj-$(CONFIG_DS1338) += ds1338.o
 common-obj-y += i2c.o smbus.o smbus_eeprom.o
 common-obj-y += eeprom93xx.o
-common-obj-y += scsi-disk.o cdrom.o hd-geometry.o block-common.o
-common-obj-y += scsi-generic.o scsi-bus.o
+common-obj-y += cdrom.o hd-geometry.o block-common.o
+common-obj-y += scsi-generic.o
+hw-obj-y += scsi-disk.o scsi-bus.o
 common-obj-y += hid.o
 common-obj-$(CONFIG_SSI) += ssi.o
 common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
diff --git a/hw/spapr_iommu.c b/hw/spapr_iommu.c
index 53b7317..54798a3 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"
 
@@ -117,7 +118,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;
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 21/23] memory: add address_space_destroy()
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (19 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 20/23] dma: make dma access its own address space Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 22/23] pci: give each device its own address space Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 23/23] pci: honor PCI_COMMAND_MASTER Avi Kivity
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Since address spaces can be created dynamically by device hotplug, they
can also be destroyed dynamically.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec.c            | 10 ++++++++++
 memory-internal.h |  1 +
 memory.c          | 18 ++++++++++++++++--
 memory.h          | 12 ++++++++++++
 4 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index 42f9ad1..68c8601 100644
--- a/exec.c
+++ b/exec.c
@@ -3246,6 +3246,16 @@ void address_space_init_dispatch(AddressSpace *as)
     memory_listener_register(&d->listener, as);
 }
 
+void address_space_destroy_dispatch(AddressSpace *as)
+{
+    AddressSpaceDispatch *d = as->dispatch;
+
+    memory_listener_unregister(&d->listener);
+    destroy_l2_mapping(&d->phys_map, P_L2_LEVELS - 1);
+    g_free(d);
+    as->dispatch = NULL;
+}
+
 static void memory_map_init(void)
 {
     system_memory = g_malloc(sizeof(*system_memory));
diff --git a/memory-internal.h b/memory-internal.h
index a9d914e..7923ced 100644
--- a/memory-internal.h
+++ b/memory-internal.h
@@ -40,6 +40,7 @@ struct AddressSpaceDispatch {
 };
 
 void address_space_init_dispatch(AddressSpace *as);
+void address_space_destroy_dispatch(AddressSpace *as);
 
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                    MemoryRegion *mr);
diff --git a/memory.c b/memory.c
index 28a79ae..a23ab72 100644
--- a/memory.c
+++ b/memory.c
@@ -558,8 +558,10 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
 
     flatview_init(&view);
 
-    render_memory_region(&view, mr, int128_zero(),
-                         addrrange_make(int128_zero(), int128_2_64()), false);
+    if (mr) {
+        render_memory_region(&view, mr, int128_zero(),
+                             addrrange_make(int128_zero(), int128_2_64()), false);
+    }
     flatview_simplify(&view);
 
     return view;
@@ -1553,6 +1555,18 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
     address_space_init_dispatch(as);
 }
 
+void address_space_destroy(AddressSpace *as)
+{
+    /* Flush out anything from MemoryListeners listening in on this */
+    memory_region_transaction_begin();
+    as->root = NULL;
+    memory_region_transaction_commit();
+    QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
+    address_space_destroy_dispatch(as);
+    flatview_destroy(as->current_map);
+    g_free(as->current_map);
+}
+
 uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
 {
     return memory_region_dispatch_read(mr, addr, size);
diff --git a/memory.h b/memory.h
index 84f7439..eab86e5 100644
--- a/memory.h
+++ b/memory.h
@@ -831,6 +831,18 @@ void mtree_info(fprintf_function mon_printf, void *f);
  */
 void address_space_init(AddressSpace *as, MemoryRegion *root);
 
+
+/**
+ * address_space_destroy: destroy an address space
+ *
+ * Releases all resources associated with an address space.  After an address space
+ * is destroyed, its root memory region (given by address_space_init()) may be destroyed
+ * as well.
+ *
+ * @as: address space to be destroyed
+ */
+void address_space_destroy(AddressSpace *as);
+
 /**
  * address_space_rw: read from or write to an address space.
  *
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 22/23] pci: give each device its own address space
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (20 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 21/23] memory: add address_space_destroy() Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 23/23] pci: honor PCI_COMMAND_MASTER Avi Kivity
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

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 <avi@redhat.com>
---
 hw/pci.c | 14 ++++++++++++++
 hw/pci.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/hw/pci.c b/hw/pci.c
index f855cf3..8e8e030 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,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)
diff --git a/hw/pci.h b/hw/pci.h
index 4b6ab3d..3192d81 100644
--- 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 */
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v1 23/23] pci: honor PCI_COMMAND_MASTER
  2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (21 preceding siblings ...)
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 22/23] pci: give each device its own address space Avi Kivity
@ 2012-10-07 12:38 ` Avi Kivity
  22 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2012-10-07 12:38 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Currently we ignore PCI_COMMAND_MASTER completely: DMA succeeds even when
the bit is clear.

Honor PCI_COMMAND_MASTER by inserting a memory region into the device's
bus master address space, and tying its enable status to PCI_COMMAND_MASTER.

Tested using

  setpci -s 03 COMMAND=3

while a ping was running on a NIC in slot 3.  The kernel (Linux) detected
the stall and recovered after the command

  setpci -s 03 COMMAND=7

was issued.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c | 13 +++++++++++--
 hw/pci.h |  1 +
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 8e8e030..7adf61b 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -782,7 +782,11 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
         /* 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());
+        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);
     }
@@ -841,6 +845,7 @@ static void do_pci_unregister_device(PCIDevice *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;
     }
@@ -1065,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 3192d81..a65e490 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -212,6 +212,7 @@ struct PCIDevice {
     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 */
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v1 04/23] xen_pt: use separate MemoryListeners for memory and I/O
  2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 04/23] xen_pt: " Avi Kivity
@ 2012-10-08 12:18   ` Stefano Stabellini
  0 siblings, 0 replies; 25+ messages in thread
From: Stefano Stabellini @ 2012-10-08 12:18 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Anthony PERARD, Michael S. Tsirkin, Stefano Stabellini,
	qemu-devel, liu ping fan, Blue Swirl, Anthony Liguori,
	Paolo Bonzini

On Sun, 7 Oct 2012, Avi Kivity wrote:
> Using an unfiltered memory listener will cause regions to be reported
> fails multiple times if we have more than two address spaces.  Use a separate
> listener for memory and I/O, and utilize MemoryListener's address space
> filtering to fix this.
> 
> Signed-off-by: Avi Kivity <avi@redhat.com>

It looks OK to me


>  hw/xen_pt.c | 38 +++++++++++++++++++++++++++++++++++++-
>  hw/xen_pt.h |  1 +
>  2 files changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/xen_pt.c b/hw/xen_pt.c
> index 307119a..438ad54 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};
> @@ -621,6 +622,22 @@ static void xen_pt_region_del(MemoryListener *l, MemoryRegionSection *sec)
>      xen_pt_region_update(s, sec, false);
>  }
>  
> +static void xen_pt_io_region_add(MemoryListener *l, MemoryRegionSection *sec)
> +{
> +    XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
> +                                             io_listener);
> +
> +    xen_pt_region_update(s, sec, true);
> +}
> +
> +static void xen_pt_io_region_del(MemoryListener *l, MemoryRegionSection *sec)
> +{
> +    XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
> +                                             io_listener);
> +
> +    xen_pt_region_update(s, sec, false);
> +}
> +
>  static void xen_pt_region_nop(MemoryListener *l, MemoryRegionSection *s)
>  {
>  }
> @@ -654,6 +671,22 @@ static void xen_pt_eventfd_fns(MemoryListener *l, MemoryRegionSection *s,
>      .priority = 10,
>  };
>  
> +static const MemoryListener xen_pt_io_listener = {
> +    .begin = xen_pt_begin,
> +    .commit = xen_pt_commit,
> +    .region_add = xen_pt_io_region_add,
> +    .region_nop = xen_pt_region_nop,
> +    .region_del = xen_pt_io_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,
> +};
> +
>  /* init */
>  
>  static int xen_pt_initfn(PCIDevice *d)
> @@ -691,6 +724,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);
> @@ -757,7 +791,8 @@ static int xen_pt_initfn(PCIDevice *d)
>      }
>  
>  out:
> -    memory_listener_register(&s->memory_listener, NULL);
> +    memory_listener_register(&s->memory_listener, get_system_memory());
> +    memory_listener_register(&s->io_listener, get_system_io());
>      XEN_PT_LOG(d, "Real physical device %02x:%02x.%d registered successfuly!\n",
>                 bus, slot, func);
>  
> @@ -812,6 +847,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);
> -- 
> 1.7.12
> 
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2012-10-08 12:19 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-07 12:38 [Qemu-devel] [PATCH v1 00/23] Integrate DMA into the memory API Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 01/23] memory: rename 'exec-obsolete.h' Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 02/23] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 03/23] kvm: use separate MemoryListeners for memory and I/O Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 04/23] xen_pt: " Avi Kivity
2012-10-08 12:18   ` Stefano Stabellini
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 05/23] memory: prepare AddressSpace for exporting Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 06/23] memory: export AddressSpace Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 07/23] memory: maintain a list of address spaces Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 08/23] memory: provide defaults for MemoryListener operations Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 09/23] memory: use new MEMORY_LISTENER_DEFAULT_OPS Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 10/23] vfio: " Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 11/23] xen_pt: " Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 12/23] kvm: " Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 13/23] xen: " Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 14/23] memory: manage coalesced mmio via a MemoryListener Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 15/23] memory: move address_space_memory and address_space_io out of memory core Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 16/23] memory: move tcg flush into a tcg memory listener Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 17/23] memory: use AddressSpace for MemoryListener filtering Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 18/23] s390: avoid reaching into memory core internals Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 19/23] memory: per-AddressSpace dispatch Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 20/23] dma: make dma access its own address space Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 21/23] memory: add address_space_destroy() Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 22/23] pci: give each device its own address space Avi Kivity
2012-10-07 12:38 ` [Qemu-devel] [PATCH v1 23/23] pci: honor PCI_COMMAND_MASTER Avi Kivity

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.