All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API
@ 2012-10-09 16:32 Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 01/23] memory: rename 'exec-obsolete.h' Avi Kivity
                   ` (20 more replies)
  0 siblings, 21 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 v2:
 - fix series numbering
 - drop MEMORY_LISTENER_DEFAULT_OPS, use traditional if (x->op) { x->op(); } instead

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

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.

Available as a git tree in:

  git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory/dma

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: drop no-op MemoryListener callbacks
  vfio: drop no-op MemoryListener callbacks
  xen_pt: drop no-op MemoryListener callbacks
  kvm: drop no-op MemoryListener callbacks
  xen: drop no-op MemoryListener callbacks
  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                               | 318 +++++++++++++++--------------------
 hw/Makefile.objs                     |   5 +-
 hw/pci.c                             |  25 ++-
 hw/pci.h                             |   2 +
 hw/spapr_iommu.c                     |   3 +-
 hw/vfio_pci.c                        |  32 +---
 hw/vhost.c                           |   5 +-
 hw/xen_pt.c                          |  47 +++---
 hw/xen_pt.h                          |   1 +
 kvm-all.c                            | 105 +++++-------
 kvm-stub.c                           |  10 --
 kvm.h                                |   2 -
 exec-obsolete.h => memory-internal.h |  31 +++-
 memory.c                             | 173 +++++++++++--------
 memory.h                             | 107 +++++++++++-
 target-s390x/misc_helper.c           |   3 +-
 xen-all.c                            |  44 +----
 22 files changed, 488 insertions(+), 483 deletions(-)
 rename exec-obsolete.h => memory-internal.h (86%)

-- 
1.7.12

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

* [Qemu-devel] [PATCH v3 01/23] memory: rename 'exec-obsolete.h'
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 02/23] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 02/23] vhost: use MemoryListener filtering to only monitor RAM address space
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 01/23] memory: rename 'exec-obsolete.h' Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 03/23] kvm: use separate MemoryListeners for memory and I/O Avi Kivity
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 03/23] kvm: use separate MemoryListeners for memory and I/O
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 01/23] memory: rename 'exec-obsolete.h' Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 02/23] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 04/23] xen_pt: " Avi Kivity
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 04/23] xen_pt: use separate MemoryListeners for memory and I/O
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (2 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 03/23] kvm: use separate MemoryListeners for memory and I/O Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 05/23] memory: prepare AddressSpace for exporting Avi Kivity
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 05/23] memory: prepare AddressSpace for exporting
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (3 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 04/23] xen_pt: " Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 06/23] memory: export AddressSpace Avi Kivity
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 06/23] memory: export AddressSpace
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (4 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 05/23] memory: prepare AddressSpace for exporting Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 07/23] memory: maintain a list of address spaces Avi Kivity
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 07/23] memory: maintain a list of address spaces
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (5 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 06/23] memory: export AddressSpace Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 08/23] memory: provide defaults for MemoryListener operations Avi Kivity
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 08/23] memory: provide defaults for MemoryListener operations
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (6 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 07/23] memory: maintain a list of address spaces Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 09/23] memory: drop no-op MemoryListener callbacks Avi Kivity
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 no-op defaults instead.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/memory.c b/memory.c
index b58b97c..269af3f 100644
--- a/memory.c
+++ b/memory.c
@@ -99,13 +99,17 @@ static bool memory_listener_match(MemoryListener *listener,
         switch (_direction) {                                           \
         case Forward:                                                   \
             QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
-                _listener->_callback(_listener, ##_args);               \
+                if (_listener->_callback) {                             \
+                    _listener->_callback(_listener, ##_args);           \
+                }                                                       \
             }                                                           \
             break;                                                      \
         case Reverse:                                                   \
             QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
                                    memory_listeners, link) {            \
-                _listener->_callback(_listener, ##_args);               \
+                if (_listener->_callback) {                             \
+                    _listener->_callback(_listener, ##_args);           \
+                }                                                       \
             }                                                           \
             break;                                                      \
         default:                                                        \
@@ -120,7 +124,8 @@ static bool memory_listener_match(MemoryListener *listener,
         switch (_direction) {                                           \
         case Forward:                                                   \
             QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
-                if (memory_listener_match(_listener, _section)) {       \
+                if (_listener->_callback                                \
+                    && memory_listener_match(_listener, _section)) {    \
                     _listener->_callback(_listener, _section, ##_args); \
                 }                                                       \
             }                                                           \
@@ -128,7 +133,8 @@ static bool memory_listener_match(MemoryListener *listener,
         case Reverse:                                                   \
             QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
                                    memory_listeners, link) {            \
-                if (memory_listener_match(_listener, _section)) {       \
+                if (_listener->_callback                                \
+                    && memory_listener_match(_listener, _section)) {    \
                     _listener->_callback(_listener, _section, ##_args); \
                 }                                                       \
             }                                                           \
@@ -1470,8 +1476,11 @@ static void listener_add_address_space(MemoryListener *listener,
     }
 
     if (global_dirty_log) {
-        listener->log_global_start(listener);
+        if (listener->log_global_start) {
+            listener->log_global_start(listener);
+        }
     }
+
     FOR_EACH_FLAT_RANGE(fr, as->current_map) {
         MemoryRegionSection section = {
             .mr = fr->mr,
@@ -1481,7 +1490,9 @@ static void listener_add_address_space(MemoryListener *listener,
             .offset_within_address_space = int128_get64(fr->addr.start),
             .readonly = fr->readonly,
         };
-        listener->region_add(listener, &section);
+        if (listener->region_add) {
+            listener->region_add(listener, &section);
+        }
     }
 }
 
-- 
1.7.12

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

* [Qemu-devel] [PATCH v3 09/23] memory: drop no-op MemoryListener callbacks
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (7 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 08/23] memory: provide defaults for MemoryListener operations Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 11/23] xen_pt: " Avi Kivity
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 | 96 ------------------------------------------------------------------
 1 file changed, 96 deletions(-)

diff --git a/exec.c b/exec.c
index 5c703b9..a16c6b4 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,19 @@ 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 = {
     .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,
     .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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 11/23] xen_pt: drop no-op MemoryListener callbacks
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (8 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 09/23] memory: drop no-op MemoryListener callbacks Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 13/23] xen: " Avi Kivity
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 | 45 ---------------------------------------------
 1 file changed, 45 deletions(-)

diff --git a/hw/xen_pt.c b/hw/xen_pt.c
index 438ad54..6f16182 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,15 @@ 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,
     .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,
     .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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 13/23] xen: drop no-op MemoryListener callbacks
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (9 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 11/23] xen_pt: " Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 14/23] memory: manage coalesced mmio via a MemoryListener Avi Kivity
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 | 42 ------------------------------------------
 1 file changed, 42 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index f76b051..cf0e0c3 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,12 @@ 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,
     .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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 14/23] memory: manage coalesced mmio via a MemoryListener
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (10 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 13/23] xen: " Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-22 12:57   ` Peter Maydell
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 15/23] memory: move address_space_memory and address_space_io out of memory core Avi Kivity
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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   | 17 +++++++++++++----
 memory.h   |  4 ++++
 6 files changed, 27 insertions(+), 39 deletions(-)

diff --git a/exec.c b/exec.c
index a16c6b4..2ee0f89 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 46cf7e9..0a3c4ae 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)
@@ -817,6 +815,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 269af3f..d829f67 100644
--- a/memory.c
+++ b/memory.c
@@ -1136,11 +1136,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,
@@ -1149,8 +1157,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));
             }
         }
     }
diff --git a/memory.h b/memory.h
index 46bc5e1..64d2b34 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;
-- 
1.7.12

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

* [Qemu-devel] [PATCH v3 15/23] memory: move address_space_memory and address_space_io out of memory core
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (11 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 14/23] memory: manage coalesced mmio via a MemoryListener Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 16/23] memory: move tcg flush into a tcg memory listener Avi Kivity
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 2ee0f89..8b67b8f 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;
 
@@ -3243,11 +3246,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 d829f67..49a6ecc 100644
--- a/memory.c
+++ b/memory.c
@@ -364,8 +364,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)
 {
@@ -454,8 +452,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;
@@ -1545,18 +1541,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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 16/23] memory: move tcg flush into a tcg memory listener
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (12 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 15/23] memory: move address_space_memory and address_space_io out of memory core Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 17/23] memory: use AddressSpace for MemoryListener filtering Avi Kivity
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index 8b67b8f..cfb8200 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;
 
@@ -3228,7 +3228,6 @@ static void io_region_del(MemoryListener *listener,
 
 static MemoryListener core_memory_listener = {
     .begin = core_begin,
-    .commit = core_commit,
     .region_add = core_region_add,
     .region_nop = core_region_nop,
     .log_global_start = core_log_global_start,
@@ -3242,6 +3241,10 @@ static void io_region_del(MemoryListener *listener,
     .priority = 0,
 };
 
+static MemoryListener tcg_memory_listener = {
+    .commit = tcg_commit,
+};
+
 static void memory_map_init(void)
 {
     system_memory = g_malloc(sizeof(*system_memory));
@@ -3256,6 +3259,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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 17/23] memory: use AddressSpace for MemoryListener filtering
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (13 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 16/23] memory: move tcg flush into a tcg memory listener Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 18/23] s390: avoid reaching into memory core internals Avi Kivity
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 cfb8200..f561fba 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;
@@ -3257,9 +3257,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 fb31f8e..e9399a1 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -1405,8 +1405,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 6f16182..8969360 100644
--- a/hw/xen_pt.c
+++ b/hw/xen_pt.c
@@ -746,8 +746,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 0a3c4ae..7b73df0 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1375,8 +1375,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 49a6ecc..0cf0177 100644
--- a/memory.c
+++ b/memory.c
@@ -147,7 +147,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),  \
@@ -593,7 +593,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),
             };
@@ -606,7 +606,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),
             };
@@ -1137,7 +1137,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),
             };
@@ -1476,7 +1476,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;
     }
 
@@ -1489,7 +1489,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),
@@ -1501,7 +1501,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 64d2b34..f5a13a4 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;
 };
 
@@ -774,7 +774,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 cf0e0c3..ea95c98 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -1116,7 +1116,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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 18/23] s390: avoid reaching into memory core internals
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (14 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 17/23] memory: use AddressSpace for MemoryListener filtering Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 21/23] memory: add address_space_destroy() Avi Kivity
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 21/23] memory: add address_space_destroy()
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (15 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 18/23] s390: avoid reaching into memory core internals Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 22/23] pci: give each device its own address space Avi Kivity
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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 ffd60c4..4bc79fb 100644
--- a/exec.c
+++ b/exec.c
@@ -3242,6 +3242,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 13be848..2f68d67 100644
--- a/memory.c
+++ b/memory.c
@@ -564,8 +564,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;
@@ -1542,6 +1544,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 d36c2ba..79393f1 100644
--- a/memory.h
+++ b/memory.h
@@ -804,6 +804,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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 22/23] pci: give each device its own address space
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (16 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 21/23] memory: add address_space_destroy() Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 23/23] pci: honor PCI_COMMAND_MASTER Avi Kivity
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* [Qemu-devel] [PATCH v3 23/23] pci: honor PCI_COMMAND_MASTER
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (17 preceding siblings ...)
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 22/23] pci: give each device its own address space Avi Kivity
@ 2012-10-09 16:32 ` Avi Kivity
  2012-10-11  3:38   ` liu ping fan
       [not found] ` <1349800368-15228-20-git-send-email-avi@redhat.com>
  2012-10-11 21:01 ` [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Anthony Liguori
  20 siblings, 1 reply; 35+ messages in thread
From: Avi Kivity @ 2012-10-09 16:32 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] 35+ messages in thread

* Re: [Qemu-devel] [PATCH v3 19/23] memory: per-AddressSpace dispatch
       [not found] ` <1349800368-15228-20-git-send-email-avi@redhat.com>
@ 2012-10-11  3:38   ` liu ping fan
  2012-10-11  8:31     ` Avi Kivity
  0 siblings, 1 reply; 35+ messages in thread
From: liu ping fan @ 2012-10-11  3:38 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Blue Swirl, Paolo Bonzini, qemu-devel, Anthony Liguori,
	Michael S. Tsirkin

On Wed, Oct 10, 2012 at 12:32 AM, Avi Kivity <avi@redhat.com> wrote:
> 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            | 175 +++++++++++++++++++++++++++++++++---------------------
>  memory-internal.h |  22 ++++++-
>  memory.c          |   1 +
>  memory.h          |  62 +++++++++++++++++++
>  6 files changed, 195 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 f561fba..ffd60c4 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);
> @@ -3228,11 +3212,9 @@ static void io_region_del(MemoryListener *listener,
>
>  static MemoryListener core_memory_listener = {
>      .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 = {
> @@ -3245,6 +3227,21 @@ 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) {
> +        .begin = mem_begin,
> +        .region_add = mem_add,

mem_add() has the fixed mapping relationship between addr(in
system_memory) and mr. If we want to fold lookup logic of iommu into
radix-tree, it will need external behavior. So I think
address_space_init_dispatch(as) should be
address_space_init_dispatch(as, listener).

Regards,
pingfan

> +        .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));
> @@ -3316,9 +3313,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;
> @@ -3330,7 +3329,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)) {
> @@ -3407,10 +3406,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;
> @@ -3421,7 +3446,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))) {
> @@ -3501,10 +3526,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;
> @@ -3519,7 +3546,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) {
> @@ -3529,7 +3556,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;
> @@ -3550,12 +3577,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) {
> @@ -3582,13 +3609,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)
> @@ -3597,7 +3637,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))) {
> @@ -3656,7 +3696,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))) {
> @@ -3723,7 +3763,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))) {
> @@ -3782,7 +3822,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);
> @@ -3814,7 +3854,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);
> @@ -3843,7 +3883,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);
> @@ -3916,7 +3956,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);
> @@ -4158,7 +4198,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 0cf0177..13be848 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1539,6 +1539,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 f5a13a4..d36c2ba 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;
>  };
>
> @@ -803,6 +804,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	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH v3 23/23] pci: honor PCI_COMMAND_MASTER
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 23/23] pci: honor PCI_COMMAND_MASTER Avi Kivity
@ 2012-10-11  3:38   ` liu ping fan
  2012-10-11  8:34     ` Avi Kivity
  0 siblings, 1 reply; 35+ messages in thread
From: liu ping fan @ 2012-10-11  3:38 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Blue Swirl, Paolo Bonzini, qemu-devel, Anthony Liguori,
	Michael S. Tsirkin

On Wed, Oct 10, 2012 at 12:32 AM, Avi Kivity <avi@redhat.com> wrote:
> 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()));

Could we achieve that  hiding special mr from some address space?  I
think one approach is to limit the iommu's lookup table, but that is
the guest's willing.  The other one is use dummy-mr to overlap some
piece of region of system_memory.
This method will require changing the render sequence of alias mr.

diff --git a/memory.c b/memory.c
index 2f68d67..cf67c66 100644
--- a/memory.c
+++ b/memory.c
@@ -499,6 +499,11 @@ static void render_memory_region(FlatView *view,

     clip = addrrange_intersection(tmp, clip);

+    /* Render subregions in priority order. */
+    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
+        render_memory_region(view, subregion, base, clip, readonly);
+    }
+
     if (mr->alias) {
         int128_subfrom(&base, int128_make64(mr->alias->addr));
         int128_subfrom(&base, int128_make64(mr->alias_offset));
@@ -506,11 +511,6 @@ static void render_memory_region(FlatView *view,
         return;
     }

-    /* Render subregions in priority order. */
-    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
-        render_memory_region(view, subregion, base, clip, readonly);
-    }
-

Regards,
pingfan

> +        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] 35+ messages in thread

* Re: [Qemu-devel] [PATCH v3 19/23] memory: per-AddressSpace dispatch
  2012-10-11  3:38   ` [Qemu-devel] [PATCH v3 19/23] memory: per-AddressSpace dispatch liu ping fan
@ 2012-10-11  8:31     ` Avi Kivity
  2012-10-11  8:45       ` liu ping fan
  0 siblings, 1 reply; 35+ messages in thread
From: Avi Kivity @ 2012-10-11  8:31 UTC (permalink / raw)
  To: liu ping fan
  Cc: Blue Swirl, Paolo Bonzini, qemu-devel, Anthony Liguori,
	Michael S. Tsirkin

On 10/11/2012 05:38 AM, liu ping fan wrote:
>>
>> +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) {
>> +        .begin = mem_begin,
>> +        .region_add = mem_add,
> 
> mem_add() has the fixed mapping relationship between addr(in
> system_memory) and mr. If we want to fold lookup logic of iommu into
> radix-tree, it will need external behavior. So I think
> address_space_init_dispatch(as) should be
> address_space_init_dispatch(as, listener).

This is per address space, it's not tied to system_memory().


-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PATCH v3 23/23] pci: honor PCI_COMMAND_MASTER
  2012-10-11  3:38   ` liu ping fan
@ 2012-10-11  8:34     ` Avi Kivity
  2012-10-11  8:49       ` liu ping fan
  0 siblings, 1 reply; 35+ messages in thread
From: Avi Kivity @ 2012-10-11  8:34 UTC (permalink / raw)
  To: liu ping fan
  Cc: Blue Swirl, Paolo Bonzini, qemu-devel, Anthony Liguori,
	Michael S. Tsirkin

On 10/11/2012 05:38 AM, liu ping fan wrote:
> On Wed, Oct 10, 2012 at 12:32 AM, Avi Kivity <avi@redhat.com> wrote:
>> 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()));
> 
> Could we achieve that  hiding special mr from some address space?  I
> think one approach is to limit the iommu's lookup table, but that is
> the guest's willing.  The other one is use dummy-mr to overlap some
> piece of region of system_memory.
> This method will require changing the render sequence of alias mr.
> 
> diff --git a/memory.c b/memory.c
> index 2f68d67..cf67c66 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -499,6 +499,11 @@ static void render_memory_region(FlatView *view,
> 
>      clip = addrrange_intersection(tmp, clip);
> 
> +    /* Render subregions in priority order. */
> +    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
> +        render_memory_region(view, subregion, base, clip, readonly);
> +    }
> +
>      if (mr->alias) {
>          int128_subfrom(&base, int128_make64(mr->alias->addr));
>          int128_subfrom(&base, int128_make64(mr->alias_offset));
> @@ -506,11 +511,6 @@ static void render_memory_region(FlatView *view,
>          return;
>      }
> 
> -    /* Render subregions in priority order. */
> -    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
> -        render_memory_region(view, subregion, base, clip, readonly);
> -    }
> -
> 

I don't really follow.  We don't have any memory region that is both a
container and an alias, so this change has no effect.  Can you describe
what you intend?


-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PATCH v3 19/23] memory: per-AddressSpace dispatch
  2012-10-11  8:31     ` Avi Kivity
@ 2012-10-11  8:45       ` liu ping fan
  2012-10-11  8:51         ` Avi Kivity
  0 siblings, 1 reply; 35+ messages in thread
From: liu ping fan @ 2012-10-11  8:45 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Blue Swirl, Paolo Bonzini, qemu-devel, Anthony Liguori,
	Michael S. Tsirkin

On Thu, Oct 11, 2012 at 4:31 PM, Avi Kivity <avi@redhat.com> wrote:
> On 10/11/2012 05:38 AM, liu ping fan wrote:
>>>
>>> +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) {
>>> +        .begin = mem_begin,
>>> +        .region_add = mem_add,
>>
>> mem_add() has the fixed mapping relationship between addr(in
>> system_memory) and mr. If we want to fold lookup logic of iommu into
>> radix-tree, it will need external behavior. So I think
>> address_space_init_dispatch(as) should be
>> address_space_init_dispatch(as, listener).
>
> This is per address space, it's not tied to system_memory().
>
Then, where do we implement iommu translation logic? Above the radix-tree?
>
> --
> error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PATCH v3 23/23] pci: honor PCI_COMMAND_MASTER
  2012-10-11  8:34     ` Avi Kivity
@ 2012-10-11  8:49       ` liu ping fan
  2012-10-11  8:53         ` Avi Kivity
  0 siblings, 1 reply; 35+ messages in thread
From: liu ping fan @ 2012-10-11  8:49 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Blue Swirl, Paolo Bonzini, qemu-devel, Anthony Liguori,
	Michael S. Tsirkin

On Thu, Oct 11, 2012 at 4:34 PM, Avi Kivity <avi@redhat.com> wrote:
> On 10/11/2012 05:38 AM, liu ping fan wrote:
>> On Wed, Oct 10, 2012 at 12:32 AM, Avi Kivity <avi@redhat.com> wrote:
>>> 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()));
>>
>> Could we achieve that  hiding special mr from some address space?  I
>> think one approach is to limit the iommu's lookup table, but that is
>> the guest's willing.  The other one is use dummy-mr to overlap some
>> piece of region of system_memory.
>> This method will require changing the render sequence of alias mr.
>>
>> diff --git a/memory.c b/memory.c
>> index 2f68d67..cf67c66 100644
>> --- a/memory.c
>> +++ b/memory.c
>> @@ -499,6 +499,11 @@ static void render_memory_region(FlatView *view,
>>
>>      clip = addrrange_intersection(tmp, clip);
>>
>> +    /* Render subregions in priority order. */
>> +    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
>> +        render_memory_region(view, subregion, base, clip, readonly);
>> +    }
>> +
>>      if (mr->alias) {
>>          int128_subfrom(&base, int128_make64(mr->alias->addr));
>>          int128_subfrom(&base, int128_make64(mr->alias_offset));
>> @@ -506,11 +511,6 @@ static void render_memory_region(FlatView *view,
>>          return;
>>      }
>>
>> -    /* Render subregions in priority order. */
>> -    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
>> -        render_memory_region(view, subregion, base, clip, readonly);
>> -    }
>> -
>>
>
> I don't really follow.  We don't have any memory region that is both a
> container and an alias, so this change has no effect.  Can you describe
> what you intend?
>
Suppose iommuA takes over only a subsection of system_memory, and
forbidden to touch other space. How can we achieve this model after
adopting this series?

>
> --
> error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PATCH v3 19/23] memory: per-AddressSpace dispatch
  2012-10-11  8:45       ` liu ping fan
@ 2012-10-11  8:51         ` Avi Kivity
  0 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-11  8:51 UTC (permalink / raw)
  To: liu ping fan
  Cc: Blue Swirl, Paolo Bonzini, qemu-devel, Anthony Liguori,
	Michael S. Tsirkin

On 10/11/2012 10:45 AM, liu ping fan wrote:
> On Thu, Oct 11, 2012 at 4:31 PM, Avi Kivity <avi@redhat.com> wrote:
>> On 10/11/2012 05:38 AM, liu ping fan wrote:
>>>>
>>>> +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) {
>>>> +        .begin = mem_begin,
>>>> +        .region_add = mem_add,
>>>
>>> mem_add() has the fixed mapping relationship between addr(in
>>> system_memory) and mr. If we want to fold lookup logic of iommu into
>>> radix-tree, it will need external behavior. So I think
>>> address_space_init_dispatch(as) should be
>>> address_space_init_dispatch(as, listener).
>>
>> This is per address space, it's not tied to system_memory().
>>
> Then, where do we implement iommu translation logic? Above the radix-tree?

I will post patches soon.  Basically each iommu does the translation,
then uses another radix tree to continue the dispatch.  Eventually we
reach the bottom.

We can't use the radix tree to resolve iommu translations because they
change dynamically and are resolved on demand, while the radix tree is
read-mostly and prepared beforehand.

-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PATCH v3 23/23] pci: honor PCI_COMMAND_MASTER
  2012-10-11  8:49       ` liu ping fan
@ 2012-10-11  8:53         ` Avi Kivity
  0 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-11  8:53 UTC (permalink / raw)
  To: liu ping fan
  Cc: Blue Swirl, Paolo Bonzini, qemu-devel, Anthony Liguori,
	Michael S. Tsirkin

On 10/11/2012 10:49 AM, liu ping fan wrote:
> On Thu, Oct 11, 2012 at 4:34 PM, Avi Kivity <avi@redhat.com> wrote:
>> On 10/11/2012 05:38 AM, liu ping fan wrote:
>>> On Wed, Oct 10, 2012 at 12:32 AM, Avi Kivity <avi@redhat.com> wrote:
>>>> 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()));
>>>
>>> Could we achieve that  hiding special mr from some address space?  I
>>> think one approach is to limit the iommu's lookup table, but that is
>>> the guest's willing.  The other one is use dummy-mr to overlap some
>>> piece of region of system_memory.
>>> This method will require changing the render sequence of alias mr.
>>>
>>> diff --git a/memory.c b/memory.c
>>> index 2f68d67..cf67c66 100644
>>> --- a/memory.c
>>> +++ b/memory.c
>>> @@ -499,6 +499,11 @@ static void render_memory_region(FlatView *view,
>>>
>>>      clip = addrrange_intersection(tmp, clip);
>>>
>>> +    /* Render subregions in priority order. */
>>> +    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
>>> +        render_memory_region(view, subregion, base, clip, readonly);
>>> +    }
>>> +
>>>      if (mr->alias) {
>>>          int128_subfrom(&base, int128_make64(mr->alias->addr));
>>>          int128_subfrom(&base, int128_make64(mr->alias_offset));
>>> @@ -506,11 +511,6 @@ static void render_memory_region(FlatView *view,
>>>          return;
>>>      }
>>>
>>> -    /* Render subregions in priority order. */
>>> -    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
>>> -        render_memory_region(view, subregion, base, clip, readonly);
>>> -    }
>>> -
>>>
>>
>> I don't really follow.  We don't have any memory region that is both a
>> container and an alias, so this change has no effect.  Can you describe
>> what you intend?
>>
> Suppose iommuA takes over only a subsection of system_memory, and
> forbidden to touch other space. How can we achieve this model after
> adopting this series?

I will soon post patches.  Basically an iommu is just another memory
region, and it can be anywhere in the memory hierarchy except it cannot
be a leaf (like an alias).


-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API
  2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
                   ` (19 preceding siblings ...)
       [not found] ` <1349800368-15228-20-git-send-email-avi@redhat.com>
@ 2012-10-11 21:01 ` Anthony Liguori
  2012-10-15 13:16   ` Avi Kivity
  20 siblings, 1 reply; 35+ messages in thread
From: Anthony Liguori @ 2012-10-11 21:01 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> 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 v2:
>  - fix series numbering
>  - drop MEMORY_LISTENER_DEFAULT_OPS, use traditional if (x->op) { x->op(); } instead
>
> Changes from v1:
>  - fix typo on commit log for patch 7
>  - add address space destruction (resolved FIXME)
>
> 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.
>
> Available as a git tree in:
>
>   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory/dma

This conflicts with a recent pull from Stefano in xen-all.c.  The
difference doesn't look that awful but since I don't have a xen test
setup, I'm not confident in resolving it myself.

Can you rebase and fixup?

Regards,

Anthony Liguori

>
> 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: drop no-op MemoryListener callbacks
>   vfio: drop no-op MemoryListener callbacks
>   xen_pt: drop no-op MemoryListener callbacks
>   kvm: drop no-op MemoryListener callbacks
>   xen: drop no-op MemoryListener callbacks
>   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                               | 318 +++++++++++++++--------------------
>  hw/Makefile.objs                     |   5 +-
>  hw/pci.c                             |  25 ++-
>  hw/pci.h                             |   2 +
>  hw/spapr_iommu.c                     |   3 +-
>  hw/vfio_pci.c                        |  32 +---
>  hw/vhost.c                           |   5 +-
>  hw/xen_pt.c                          |  47 +++---
>  hw/xen_pt.h                          |   1 +
>  kvm-all.c                            | 105 +++++-------
>  kvm-stub.c                           |  10 --
>  kvm.h                                |   2 -
>  exec-obsolete.h => memory-internal.h |  31 +++-
>  memory.c                             | 173 +++++++++++--------
>  memory.h                             | 107 +++++++++++-
>  target-s390x/misc_helper.c           |   3 +-
>  xen-all.c                            |  44 +----
>  22 files changed, 488 insertions(+), 483 deletions(-)
>  rename exec-obsolete.h => memory-internal.h (86%)
>
> -- 
> 1.7.12

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

* Re: [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API
  2012-10-11 21:01 ` [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Anthony Liguori
@ 2012-10-15 13:16   ` Avi Kivity
  2012-10-22  9:35     ` Avi Kivity
  0 siblings, 1 reply; 35+ messages in thread
From: Avi Kivity @ 2012-10-15 13:16 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

On 10/11/2012 11:01 PM, Anthony Liguori wrote:
> This conflicts with a recent pull from Stefano in xen-all.c.  The
> difference doesn't look that awful but since I don't have a xen test
> setup, I'm not confident in resolving it myself.
> 
> Can you rebase and fixup?
> 

Rebased tree in the same place:

  git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory/dma



-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API
  2012-10-15 13:16   ` Avi Kivity
@ 2012-10-22  9:35     ` Avi Kivity
  2012-10-22 12:39       ` Peter Maydell
  0 siblings, 1 reply; 35+ messages in thread
From: Avi Kivity @ 2012-10-22  9:35 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

On 10/15/2012 03:16 PM, Avi Kivity wrote:
> On 10/11/2012 11:01 PM, Anthony Liguori wrote:
>> This conflicts with a recent pull from Stefano in xen-all.c.  The
>> difference doesn't look that awful but since I don't have a xen test
>> setup, I'm not confident in resolving it myself.
>> 
>> Can you rebase and fixup?
>> 
> 
> Rebased tree in the same place:
> 
>   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory/dma
> 

Anthony, or Blue, can you pull please?  The neighbours are starting to
complain about the smell.


-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API
  2012-10-22  9:35     ` Avi Kivity
@ 2012-10-22 12:39       ` Peter Maydell
  2012-10-22 19:46         ` Anthony Liguori
  0 siblings, 1 reply; 35+ messages in thread
From: Peter Maydell @ 2012-10-22 12:39 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Michael S. Tsirkin, liu ping fan, qemu-devel, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 22 October 2012 10:35, Avi Kivity <avi@redhat.com> wrote:
> On 10/15/2012 03:16 PM, Avi Kivity wrote:
>> Rebased tree in the same place:
>>
>>   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory/dma
>>
>
> Anthony, or Blue, can you pull please?  The neighbours are starting to
> complain about the smell.

Yes, please -- there's a patch in my nearly-ready-to-post v3
KVM-ARM RFC series which will want these changes...

-- PMM

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

* Re: [Qemu-devel] [PATCH v3 14/23] memory: manage coalesced mmio via a MemoryListener
  2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 14/23] memory: manage coalesced mmio via a MemoryListener Avi Kivity
@ 2012-10-22 12:57   ` Peter Maydell
  2012-10-22 13:00     ` Avi Kivity
  0 siblings, 1 reply; 35+ messages in thread
From: Peter Maydell @ 2012-10-22 12:57 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Michael S. Tsirkin, qemu-devel, liu ping fan, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 9 October 2012 17:32, Avi Kivity <avi@redhat.com> wrote:
> 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.

> -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)
>  {

> +    void (*coalesced_mmio_add)(MemoryListener *listener, MemoryRegionSection *section,
> +                               target_phys_addr_t addr, target_phys_addr_t len);

These disagree about the type of the 'size/len' parameter, which means
this doesn't compile on 32-bit systems where target_phys_addr_t is 64
bits but ram_addr_t is 32 bits:

/home/petmay01/git/qemu/kvm-all.c:818:5: error: initialization from
incompatible pointer type [-Werror]
/home/petmay01/git/qemu/kvm-all.c:818:5: error: (near initialization
for ‘kvm_memory_listener.coalesced_mmio_add’) [-Werror]
/home/petmay01/git/qemu/kvm-all.c:819:5: error: initialization from
incompatible pointer type [-Werror]
/home/petmay01/git/qemu/kvm-all.c:819:5: error: (near initialization
for ‘kvm_memory_listener.coalesced_mmio_del’) [-Werror]

-- PMM

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

* Re: [Qemu-devel] [PATCH v3 14/23] memory: manage coalesced mmio via a MemoryListener
  2012-10-22 12:57   ` Peter Maydell
@ 2012-10-22 13:00     ` Avi Kivity
  0 siblings, 0 replies; 35+ messages in thread
From: Avi Kivity @ 2012-10-22 13:00 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Michael S. Tsirkin, qemu-devel, liu ping fan, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 10/22/2012 02:57 PM, Peter Maydell wrote:
> On 9 October 2012 17:32, Avi Kivity <avi@redhat.com> wrote:
>> 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.
> 
>> -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)
>>  {
> 
>> +    void (*coalesced_mmio_add)(MemoryListener *listener, MemoryRegionSection *section,
>> +                               target_phys_addr_t addr, target_phys_addr_t len);
> 
> These disagree about the type of the 'size/len' parameter, which means
> this doesn't compile on 32-bit systems where target_phys_addr_t is 64
> bits but ram_addr_t is 32 bits:
> 
> /home/petmay01/git/qemu/kvm-all.c:818:5: error: initialization from
> incompatible pointer type [-Werror]
> /home/petmay01/git/qemu/kvm-all.c:818:5: error: (near initialization
> for ‘kvm_memory_listener.coalesced_mmio_add’) [-Werror]
> /home/petmay01/git/qemu/kvm-all.c:819:5: error: initialization from
> incompatible pointer type [-Werror]
> /home/petmay01/git/qemu/kvm-all.c:819:5: error: (near initialization
> for ‘kvm_memory_listener.coalesced_mmio_del’) [-Werror]

Thanks, fixed and re-pushed.

New HEAD is 1c380f9460522f.

-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API
  2012-10-22 12:39       ` Peter Maydell
@ 2012-10-22 19:46         ` Anthony Liguori
  0 siblings, 0 replies; 35+ messages in thread
From: Anthony Liguori @ 2012-10-22 19:46 UTC (permalink / raw)
  To: Peter Maydell, Avi Kivity
  Cc: Blue Swirl, Paolo Bonzini, liu ping fan, qemu-devel, Michael S. Tsirkin

Peter Maydell <peter.maydell@linaro.org> writes:

> On 22 October 2012 10:35, Avi Kivity <avi@redhat.com> wrote:
>> On 10/15/2012 03:16 PM, Avi Kivity wrote:
>>> Rebased tree in the same place:
>>>
>>>   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory/dma
>>>
>>
>> Anthony, or Blue, can you pull please?  The neighbours are starting to
>> complain about the smell.
>
> Yes, please -- there's a patch in my nearly-ready-to-post v3
> KVM-ARM RFC series which will want these changes...

Pulled. Thanks.

Regards,

Anthony Liguori

>
> -- PMM

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

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

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-09 16:32 [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 01/23] memory: rename 'exec-obsolete.h' Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 02/23] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 03/23] kvm: use separate MemoryListeners for memory and I/O Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 04/23] xen_pt: " Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 05/23] memory: prepare AddressSpace for exporting Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 06/23] memory: export AddressSpace Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 07/23] memory: maintain a list of address spaces Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 08/23] memory: provide defaults for MemoryListener operations Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 09/23] memory: drop no-op MemoryListener callbacks Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 11/23] xen_pt: " Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 13/23] xen: " Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 14/23] memory: manage coalesced mmio via a MemoryListener Avi Kivity
2012-10-22 12:57   ` Peter Maydell
2012-10-22 13:00     ` Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 15/23] memory: move address_space_memory and address_space_io out of memory core Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 16/23] memory: move tcg flush into a tcg memory listener Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 17/23] memory: use AddressSpace for MemoryListener filtering Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 18/23] s390: avoid reaching into memory core internals Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 21/23] memory: add address_space_destroy() Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 22/23] pci: give each device its own address space Avi Kivity
2012-10-09 16:32 ` [Qemu-devel] [PATCH v3 23/23] pci: honor PCI_COMMAND_MASTER Avi Kivity
2012-10-11  3:38   ` liu ping fan
2012-10-11  8:34     ` Avi Kivity
2012-10-11  8:49       ` liu ping fan
2012-10-11  8:53         ` Avi Kivity
     [not found] ` <1349800368-15228-20-git-send-email-avi@redhat.com>
2012-10-11  3:38   ` [Qemu-devel] [PATCH v3 19/23] memory: per-AddressSpace dispatch liu ping fan
2012-10-11  8:31     ` Avi Kivity
2012-10-11  8:45       ` liu ping fan
2012-10-11  8:51         ` Avi Kivity
2012-10-11 21:01 ` [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API Anthony Liguori
2012-10-15 13:16   ` Avi Kivity
2012-10-22  9:35     ` Avi Kivity
2012-10-22 12:39       ` Peter Maydell
2012-10-22 19:46         ` Anthony Liguori

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.