All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API
@ 2012-10-03 16:03 Avi Kivity
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 01/22] memory: rename 'exec-obsolete.h' Avi Kivity
                   ` (24 more replies)
  0 siblings, 25 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:03 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.

Avi Kivity (22):
  memory: rename 'exec-obsolete.h'
  vhost: use MemoryListener filtering to only monitor RAM address space
  kvm: use separate MemoryListeners for memory and I/O
  xen_pt: use separate MemoryListeners for memory and I/O
  memory: prepare AddressSpace for exporting
  memory: export AddressSpace
  memory: maintain a list of address spaces
  memory: provide defaults for MemoryListener operations
  memory: use new MEMORY_LISTENER_DEFAULT_OPS
  vfio: use new MEMORY_LISTENER_DEFAULT_OPS
  xen_pt: use new MEMORY_LISTENER_DEFAULT_OPS
  kvm: use new MEMORY_LISTENER_DEFAULT_OPS
  xen: use new MEMORY_LISTENER_DEFAULT_OPS
  memory: manage coalesced mmio via a MemoryListener
  memory: move address_space_memory and address_space_io out of memory
    core
  memory: move tcg flush into a tcg memory listener
  memory: use AddressSpace for MemoryListener filtering
  s390: avoid reaching into memory core internals
  memory: per-AddressSpace dispatch
  dma: make dma access its own address space
  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                               | 312 ++++++++++++++---------------------
 hw/Makefile.objs                     |   5 +-
 hw/pci.c                             |  19 ++-
 hw/pci.h                             |   2 +
 hw/spapr_iommu.c                     |   3 +-
 hw/vfio_pci.c                        |  33 +---
 hw/vhost.c                           |   5 +-
 hw/xen_pt.c                          |  49 +++---
 hw/xen_pt.h                          |   1 +
 kvm-all.c                            | 107 +++++-------
 kvm-stub.c                           |  10 --
 kvm.h                                |   2 -
 exec-obsolete.h => memory-internal.h |  30 +++-
 memory.c                             | 158 +++++++++++-------
 memory.h                             | 122 +++++++++++++-
 target-s390x/misc_helper.c           |   2 +-
 xen-all.c                            |  45 +----
 22 files changed, 487 insertions(+), 476 deletions(-)
 rename exec-obsolete.h => memory-internal.h (87%)

-- 
1.7.12

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

* [Qemu-devel] [RFC v1 01/22] memory: rename 'exec-obsolete.h'
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
@ 2012-10-03 16:03 ` Avi Kivity
  2012-10-04 13:58   ` Anthony Liguori
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 02/22] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
                   ` (23 subsequent siblings)
  24 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:03 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.

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

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

* [Qemu-devel] [RFC v1 03/22] kvm: use separate MemoryListeners for memory and I/O
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 01/22] memory: rename 'exec-obsolete.h' Avi Kivity
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 02/22] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
@ 2012-10-03 16:03 ` Avi Kivity
  2012-10-03 20:16   ` Blue Swirl
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 04/22] xen_pt: " Avi Kivity
                   ` (21 subsequent siblings)
  24 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:03 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] 70+ messages in thread

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

* [Qemu-devel] [RFC v1 05/22] memory: prepare AddressSpace for exporting
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (3 preceding siblings ...)
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 04/22] xen_pt: " Avi Kivity
@ 2012-10-03 16:03 ` Avi Kivity
  2012-10-04 14:01   ` Anthony Liguori
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 06/22] memory: export AddressSpace Avi Kivity
                   ` (19 subsequent siblings)
  24 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:03 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.

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

* [Qemu-devel] [RFC v1 06/22] memory: export AddressSpace
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (4 preceding siblings ...)
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 05/22] memory: prepare AddressSpace for exporting Avi Kivity
@ 2012-10-03 16:03 ` Avi Kivity
  2012-10-04 14:02   ` Anthony Liguori
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 07/22] memory: maintain a list of address spaces Avi Kivity
                   ` (18 subsequent siblings)
  24 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:03 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.

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

* [Qemu-devel] [RFC v1 07/22] memory: maintain a list of address spaces
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (5 preceding siblings ...)
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 06/22] memory: export AddressSpace Avi Kivity
@ 2012-10-03 16:03 ` Avi Kivity
  2012-10-04 10:17   ` Gleb Natapov
  2012-10-04 14:03   ` Anthony Liguori
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 08/22] memory: provide defaults for MemoryListener operations Avi Kivity
                   ` (17 subsequent siblings)
  24 siblings, 2 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:03 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 but masters.

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

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

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

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

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

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

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

Removes quite a bit of useless code.

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

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

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

* [Qemu-devel] [RFC v1 10/22] vfio: use new MEMORY_LISTENER_DEFAULT_OPS
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (8 preceding siblings ...)
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 09/22] memory: use new MEMORY_LISTENER_DEFAULT_OPS Avi Kivity
@ 2012-10-03 16:03 ` Avi Kivity
  2012-10-04 15:45   ` Alex Williamson
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 11/22] xen_pt: " Avi Kivity
                   ` (14 subsequent siblings)
  24 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:03 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/vfio_pci.c | 30 +-----------------------------
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index a1eeced..8e49535 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -803,25 +803,6 @@ static int vfio_dma_unmap(VFIOContainer *container,
     return 0;
 }
 
-static void vfio_listener_dummy1(MemoryListener *listener)
-{
-    /* We don't do batching (begin/commit) or care about logging */
-}
-
-static void vfio_listener_dummy2(MemoryListener *listener,
-                                 MemoryRegionSection *section)
-{
-    /* We don't do logging or care about nops */
-}
-
-static void vfio_listener_dummy3(MemoryListener *listener,
-                                 MemoryRegionSection *section,
-                                 bool match_data, uint64_t data,
-                                 EventNotifier *e)
-{
-    /* We don't care about eventfds */
-}
-
 static bool vfio_listener_skipped_section(MemoryRegionSection *section)
 {
     return !memory_region_is_ram(section->mr);
@@ -913,18 +894,9 @@ static void vfio_listener_region_del(MemoryListener *listener,
 }
 
 static MemoryListener vfio_memory_listener = {
-    .begin = vfio_listener_dummy1,
-    .commit = vfio_listener_dummy1,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .region_add = vfio_listener_region_add,
     .region_del = vfio_listener_region_del,
-    .region_nop = vfio_listener_dummy2,
-    .log_start = vfio_listener_dummy2,
-    .log_stop = vfio_listener_dummy2,
-    .log_sync = vfio_listener_dummy2,
-    .log_global_start = vfio_listener_dummy1,
-    .log_global_stop = vfio_listener_dummy1,
-    .eventfd_add = vfio_listener_dummy3,
-    .eventfd_del = vfio_listener_dummy3,
 };
 
 static void vfio_listener_release(VFIOContainer *container)
-- 
1.7.12

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

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

Removes quite a bit of useless code.

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

diff --git a/hw/xen_pt.c b/hw/xen_pt.c
index 438ad54..4dcf46a 100644
--- a/hw/xen_pt.c
+++ b/hw/xen_pt.c
@@ -598,14 +598,6 @@ static void xen_pt_region_update(XenPCIPassthroughState *s,
     }
 }
 
-static void xen_pt_begin(MemoryListener *l)
-{
-}
-
-static void xen_pt_commit(MemoryListener *l)
-{
-}
-
 static void xen_pt_region_add(MemoryListener *l, MemoryRegionSection *sec)
 {
     XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
@@ -638,52 +630,17 @@ static void xen_pt_io_region_del(MemoryListener *l, MemoryRegionSection *sec)
     xen_pt_region_update(s, sec, false);
 }
 
-static void xen_pt_region_nop(MemoryListener *l, MemoryRegionSection *s)
-{
-}
-
-static void xen_pt_log_fns(MemoryListener *l, MemoryRegionSection *s)
-{
-}
-
-static void xen_pt_log_global_fns(MemoryListener *l)
-{
-}
-
-static void xen_pt_eventfd_fns(MemoryListener *l, MemoryRegionSection *s,
-                               bool match_data, uint64_t data, EventNotifier *n)
-{
-}
-
 static const MemoryListener xen_pt_memory_listener = {
-    .begin = xen_pt_begin,
-    .commit = xen_pt_commit,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .region_add = xen_pt_region_add,
-    .region_nop = xen_pt_region_nop,
     .region_del = xen_pt_region_del,
-    .log_start = xen_pt_log_fns,
-    .log_stop = xen_pt_log_fns,
-    .log_sync = xen_pt_log_fns,
-    .log_global_start = xen_pt_log_global_fns,
-    .log_global_stop = xen_pt_log_global_fns,
-    .eventfd_add = xen_pt_eventfd_fns,
-    .eventfd_del = xen_pt_eventfd_fns,
     .priority = 10,
 };
 
 static const MemoryListener xen_pt_io_listener = {
-    .begin = xen_pt_begin,
-    .commit = xen_pt_commit,
+    MEMORY_LISTENER_DEFAULT_OPS,
     .region_add = xen_pt_io_region_add,
-    .region_nop = xen_pt_region_nop,
     .region_del = xen_pt_io_region_del,
-    .log_start = xen_pt_log_fns,
-    .log_stop = xen_pt_log_fns,
-    .log_sync = xen_pt_log_fns,
-    .log_global_start = xen_pt_log_global_fns,
-    .log_global_stop = xen_pt_log_global_fns,
-    .eventfd_add = xen_pt_eventfd_fns,
-    .eventfd_del = xen_pt_eventfd_fns,
     .priority = 10,
 };
 
-- 
1.7.12

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

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

Removes quite a bit of useless code.

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

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

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

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

Removes quite a bit of useless code.

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

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

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

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

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

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

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

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

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

* [Qemu-devel] [RFC v1 15/22] memory: move address_space_memory and address_space_io out of memory core
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (13 preceding siblings ...)
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 14/22] memory: manage coalesced mmio via a MemoryListener Avi Kivity
@ 2012-10-03 16:03 ` Avi Kivity
  2012-10-04 14:08   ` Anthony Liguori
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 16/22] memory: move tcg flush into a tcg memory listener Avi Kivity
                   ` (9 subsequent siblings)
  24 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:03 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.

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

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

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

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

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

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

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

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

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

* [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (15 preceding siblings ...)
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 16/22] memory: move tcg flush into a tcg memory listener Avi Kivity
@ 2012-10-03 16:04 ` Avi Kivity
  2012-10-03 20:16   ` Blue Swirl
  2012-10-04 14:09   ` Anthony Liguori
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 18/22] s390: avoid reaching into memory core internals Avi Kivity
                   ` (7 subsequent siblings)
  24 siblings, 2 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:04 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.

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

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

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

* [Qemu-devel] [RFC v1 18/22] s390: avoid reaching into memory core internals
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (16 preceding siblings ...)
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering Avi Kivity
@ 2012-10-03 16:04 ` Avi Kivity
  2012-10-04  8:12   ` Christian Borntraeger
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch Avi Kivity
                   ` (6 subsequent siblings)
  24 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:04 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 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index e9b3cae..2da4c90 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -81,7 +81,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] 70+ messages in thread

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

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

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

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

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

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

* [Qemu-devel] [RFC v1 20/22] dma: make dma access its own address space
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (18 preceding siblings ...)
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch Avi Kivity
@ 2012-10-03 16:04 ` Avi Kivity
  2012-10-04 14:15   ` Anthony Liguori
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 21/22] pci: give each device " Avi Kivity
                   ` (4 subsequent siblings)
  24 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:04 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

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

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

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

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

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

* [Qemu-devel] [RFC v1 21/22] pci: give each device its own address space
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (19 preceding siblings ...)
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 20/22] dma: make dma access its own address space Avi Kivity
@ 2012-10-03 16:04 ` Avi Kivity
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 22/22] pci: honor PCI_COMMAND_MASTER Avi Kivity
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:04 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.

FIXME: address space destruction.

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

diff --git a/hw/pci.c b/hw/pci.c
index f855cf3..ecea286 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,7 @@ 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);
+    /* FIXME: destroy pci_dev->bus_master_as */
 }
 
 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] 70+ messages in thread

* [Qemu-devel] [RFC v1 22/22] pci: honor PCI_COMMAND_MASTER
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (20 preceding siblings ...)
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 21/22] pci: give each device " Avi Kivity
@ 2012-10-03 16:04 ` Avi Kivity
  2012-10-03 20:26 ` [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Blue Swirl
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-03 16:04 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 | 12 ++++++++++--
 hw/pci.h |  1 +
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index ecea286..6ba5ae5 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);
     }
@@ -1060,8 +1064,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] 70+ messages in thread

* Re: [Qemu-devel] [RFC v1 03/22] kvm: use separate MemoryListeners for memory and I/O
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 03/22] kvm: use separate MemoryListeners for memory and I/O Avi Kivity
@ 2012-10-03 20:16   ` Blue Swirl
  2012-10-04  6:33     ` Avi Kivity
  0 siblings, 1 reply; 70+ messages in thread
From: Blue Swirl @ 2012-10-03 20:16 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On Wed, Oct 3, 2012 at 4:03 PM, Avi Kivity <avi@redhat.com> wrote:
> 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 = {

const

> +    .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	[flat|nested] 70+ messages in thread

* Re: [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering Avi Kivity
@ 2012-10-03 20:16   ` Blue Swirl
  2012-10-04 10:17     ` Avi Kivity
  2012-10-04 14:09   ` Anthony Liguori
  1 sibling, 1 reply; 70+ messages in thread
From: Blue Swirl @ 2012-10-03 20:16 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On Wed, Oct 3, 2012 at 4:04 PM, Avi Kivity <avi@redhat.com> wrote:
> Using the AddressSpace type reduces confusion, as you can't accidentally
> supply the MemoryRegion you're interested in.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  exec-memory.h |  3 +++
>  exec.c        | 10 +++++-----
>  hw/vfio_pci.c |  3 +--
>  hw/vhost.c    |  2 +-
>  hw/xen_pt.c   |  4 ++--
>  kvm-all.c     |  4 ++--
>  memory.c      | 14 +++++++-------
>  memory.h      |  6 +++---
>  xen-all.c     |  2 +-
>  9 files changed, 25 insertions(+), 23 deletions(-)
>
> diff --git a/exec-memory.h b/exec-memory.h
> index 6707e40..ac1d07d 100644
> --- a/exec-memory.h
> +++ b/exec-memory.h
> @@ -33,6 +33,9 @@ MemoryRegion *get_system_memory(void);
>   */
>  MemoryRegion *get_system_io(void);
>
> +extern AddressSpace address_space_memory;
> +extern AddressSpace address_space_io;
> +
>  #endif
>
>  #endif
> diff --git a/exec.c b/exec.c
> index 3c46298..7a76efa 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -116,8 +116,8 @@
>  static MemoryRegion *system_memory;
>  static MemoryRegion *system_io;
>
> -static AddressSpace address_space_io;
> -static AddressSpace address_space_memory;
> +AddressSpace address_space_io;
> +AddressSpace address_space_memory;
>
>  MemoryRegion io_mem_ram, io_mem_rom, io_mem_unassigned, io_mem_notdirty;
>  static MemoryRegion io_mem_subpage_ram;
> @@ -3260,9 +3260,9 @@ static void memory_map_init(void)
>      address_space_init(&address_space_io, system_io);
>      address_space_io.name = "I/O";
>
> -    memory_listener_register(&core_memory_listener, system_memory);
> -    memory_listener_register(&io_memory_listener, system_io);
> -    memory_listener_register(&tcg_memory_listener, system_memory);
> +    memory_listener_register(&core_memory_listener, &address_space_memory);
> +    memory_listener_register(&io_memory_listener, &address_space_io);
> +    memory_listener_register(&tcg_memory_listener, &address_space_memory);
>  }
>
>  MemoryRegion *get_system_memory(void)
> diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
> index 8e49535..dc6c776 100644
> --- a/hw/vfio_pci.c
> +++ b/hw/vfio_pci.c
> @@ -1406,8 +1406,7 @@ static int vfio_connect_container(VFIOGroup *group)
>          container->iommu_data.listener = vfio_memory_listener;
>          container->iommu_data.release = vfio_listener_release;
>
> -        memory_listener_register(&container->iommu_data.listener,
> -                                 get_system_memory());
> +        memory_listener_register(&container->iommu_data.listener, &address_space_memory);
>      } else {
>          error_report("vfio: No available IOMMU models\n");
>          g_free(container);
> diff --git a/hw/vhost.c b/hw/vhost.c
> index 100f765..0b4ac3f 100644
> --- a/hw/vhost.c
> +++ b/hw/vhost.c
> @@ -792,7 +792,7 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath,
>      hdev->log_size = 0;
>      hdev->log_enabled = false;
>      hdev->started = false;
> -    memory_listener_register(&hdev->memory_listener, get_system_memory());
> +    memory_listener_register(&hdev->memory_listener, &address_space_memory);
>      hdev->force = force;
>      return 0;
>  fail:
> diff --git a/hw/xen_pt.c b/hw/xen_pt.c
> index 4dcf46a..5a527eb 100644
> --- a/hw/xen_pt.c
> +++ b/hw/xen_pt.c
> @@ -748,8 +748,8 @@ static int xen_pt_initfn(PCIDevice *d)
>      }
>
>  out:
> -    memory_listener_register(&s->memory_listener, get_system_memory());
> -    memory_listener_register(&s->io_listener, get_system_io());
> +    memory_listener_register(&s->memory_listener, &address_space_memory);
> +    memory_listener_register(&s->io_listener, &address_space_io);
>      XEN_PT_LOG(d, "Real physical device %02x:%02x.%d registered successfuly!\n",
>                 bus, slot, func);
>
> diff --git a/kvm-all.c b/kvm-all.c
> index 25ca202..5859d37 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1377,8 +1377,8 @@ int kvm_init(void)
>      }
>
>      kvm_state = s;
> -    memory_listener_register(&kvm_memory_listener, get_system_memory());
> -    memory_listener_register(&kvm_io_listener, get_system_io());
> +    memory_listener_register(&kvm_memory_listener, &address_space_memory);
> +    memory_listener_register(&kvm_io_listener, &address_space_io);
>
>      s->many_ioeventfds = kvm_check_many_ioeventfds();
>
> diff --git a/memory.c b/memory.c
> index 7bc5a32..f829d84 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -141,7 +141,7 @@ static bool memory_listener_match(MemoryListener *listener,
>  #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
>      MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) {       \
>          .mr = (fr)->mr,                                                 \
> -        .address_space = (as)->root,                                    \
> +        .address_space = (as),                                          \

Maybe remove parenthesis.

>          .offset_within_region = (fr)->offset_in_region,                 \
>          .size = int128_get64((fr)->addr.size),                          \
>          .offset_within_address_space = int128_get64((fr)->addr.start),  \
> @@ -587,7 +587,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
>                                                    fds_new[inew]))) {
>              fd = &fds_old[iold];
>              section = (MemoryRegionSection) {
> -                .address_space = as->root,
> +                .address_space = as,
>                  .offset_within_address_space = int128_get64(fd->addr.start),
>                  .size = int128_get64(fd->addr.size),
>              };
> @@ -600,7 +600,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
>                                                           fds_old[iold]))) {
>              fd = &fds_new[inew];
>              section = (MemoryRegionSection) {
> -                .address_space = as->root,
> +                .address_space = as,
>                  .offset_within_address_space = int128_get64(fd->addr.start),
>                  .size = int128_get64(fd->addr.size),
>              };
> @@ -1131,7 +1131,7 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
>      FOR_EACH_FLAT_RANGE(fr, as->current_map) {
>          if (fr->mr == mr) {
>              section = (MemoryRegionSection) {
> -                .address_space = as->root,
> +                .address_space = as,
>                  .offset_within_address_space = int128_get64(fr->addr.start),
>                  .size = int128_get64(fr->addr.size),
>              };
> @@ -1470,7 +1470,7 @@ static void listener_add_address_space(MemoryListener *listener,
>      FlatRange *fr;
>
>      if (listener->address_space_filter
> -        && listener->address_space_filter != as->root) {
> +        && listener->address_space_filter != as) {
>          return;
>      }
>
> @@ -1480,7 +1480,7 @@ static void listener_add_address_space(MemoryListener *listener,
>      FOR_EACH_FLAT_RANGE(fr, as->current_map) {
>          MemoryRegionSection section = {
>              .mr = fr->mr,
> -            .address_space = as->root,
> +            .address_space = as,
>              .offset_within_region = fr->offset_in_region,
>              .size = int128_get64(fr->addr.size),
>              .offset_within_address_space = int128_get64(fr->addr.start),
> @@ -1490,7 +1490,7 @@ static void listener_add_address_space(MemoryListener *listener,
>      }
>  }
>
> -void memory_listener_register(MemoryListener *listener, MemoryRegion *filter)
> +void memory_listener_register(MemoryListener *listener, AddressSpace *filter)
>  {
>      MemoryListener *other = NULL;
>      AddressSpace *as;
> diff --git a/memory.h b/memory.h
> index 5f50bce..6115f48 100644
> --- a/memory.h
> +++ b/memory.h
> @@ -187,7 +187,7 @@ typedef struct MemoryRegionSection MemoryRegionSection;
>   */
>  struct MemoryRegionSection {
>      MemoryRegion *mr;
> -    MemoryRegion *address_space;
> +    AddressSpace *address_space;
>      target_phys_addr_t offset_within_region;
>      uint64_t size;
>      target_phys_addr_t offset_within_address_space;
> @@ -223,7 +223,7 @@ struct MemoryListener {
>                                 target_phys_addr_t addr, target_phys_addr_t len);
>      /* Lower = earlier (during add), later (during del) */
>      unsigned priority;
> -    MemoryRegion *address_space_filter;
> +    AddressSpace *address_space_filter;
>      QTAILQ_ENTRY(MemoryListener) link;
>  };
>
> @@ -801,7 +801,7 @@ void memory_region_transaction_commit(void);
>   * @listener: an object containing the callbacks to be called
>   * @filter: if non-%NULL, only regions in this address space will be observed
>   */
> -void memory_listener_register(MemoryListener *listener, MemoryRegion *filter);
> +void memory_listener_register(MemoryListener *listener, AddressSpace *filter);
>
>  /**
>   * memory_listener_unregister: undo the effect of memory_listener_register()
> diff --git a/xen-all.c b/xen-all.c
> index 823e043..85f799b 100644
> --- a/xen-all.c
> +++ b/xen-all.c
> @@ -1117,7 +1117,7 @@ int xen_hvm_init(void)
>
>      state->memory_listener = xen_memory_listener;
>      QLIST_INIT(&state->physmap);
> -    memory_listener_register(&state->memory_listener, get_system_memory());
> +    memory_listener_register(&state->memory_listener, &address_space_memory);
>      state->log_for_dirtybit = NULL;
>
>      /* Initialize backend core & drivers */
> --
> 1.7.12
>

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch Avi Kivity
@ 2012-10-03 20:24   ` Blue Swirl
  2012-10-04  6:38     ` Avi Kivity
  2012-10-04 14:13   ` Anthony Liguori
  1 sibling, 1 reply; 70+ messages in thread
From: Blue Swirl @ 2012-10-03 20:24 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On Wed, Oct 3, 2012 at 4:04 PM, 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            | 176 +++++++++++++++++++++++++++++++++---------------------
>  memory-internal.h |  22 ++++++-
>  memory.c          |   1 +
>  memory.h          |  62 +++++++++++++++++++
>  6 files changed, 196 insertions(+), 71 deletions(-)
>
> diff --git a/cputlb.c b/cputlb.c
> index 0627f32..9027557 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -21,6 +21,7 @@
>  #include "cpu.h"
>  #include "exec-all.h"
>  #include "memory.h"
> +#include "exec-memory.h"
>
>  #include "cputlb.h"
>
> @@ -251,7 +252,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
>      if (size != TARGET_PAGE_SIZE) {
>          tlb_add_large_page(env, vaddr, size);
>      }
> -    section = phys_page_find(paddr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, paddr >> TARGET_PAGE_BITS);
>  #if defined(DEBUG_TLB)
>      printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
>             " prot=%x idx=%d pd=0x%08lx\n",
> diff --git a/cputlb.h b/cputlb.h
> index 2dc2c96..d537b77 100644
> --- a/cputlb.h
> +++ b/cputlb.h
> @@ -26,7 +26,8 @@ void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
>                               target_ulong vaddr);
>  void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
>                             uintptr_t length);
> -MemoryRegionSection *phys_page_find(target_phys_addr_t index);
> +MemoryRegionSection *phys_page_find(struct AddressSpaceDispatch *d,
> +                                    target_phys_addr_t index);
>  void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
>  void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
>  extern int tlb_flush_count;
> diff --git a/exec.c b/exec.c
> index 7a76efa..42f9ad1 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -187,7 +187,6 @@
>  static void *l1_map[V_L1_SIZE];
>
>  #if !defined(CONFIG_USER_ONLY)
> -typedef struct PhysPageEntry PhysPageEntry;
>
>  static MemoryRegionSection *phys_sections;
>  static unsigned phys_sections_nb, phys_sections_nb_alloc;
> @@ -196,22 +195,12 @@
>  static uint16_t phys_section_rom;
>  static uint16_t phys_section_watch;
>
> -struct PhysPageEntry {
> -    uint16_t is_leaf : 1;
> -     /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
> -    uint16_t ptr : 15;
> -};
> -
>  /* Simple allocator for PhysPageEntry nodes */
>  static PhysPageEntry (*phys_map_nodes)[L2_SIZE];
>  static unsigned phys_map_nodes_nb, phys_map_nodes_nb_alloc;
>
>  #define PHYS_MAP_NODE_NIL (((uint16_t)~0) >> 1)
>
> -/* This is a multi-level map on the physical address space.
> -   The bottom level has pointers to MemoryRegionSections.  */
> -static PhysPageEntry phys_map = { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
> -
>  static void io_mem_init(void);
>  static void memory_map_init(void);
>
> @@ -459,18 +448,19 @@ static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t *index,
>      }
>  }
>
> -static void phys_page_set(target_phys_addr_t index, target_phys_addr_t nb,
> +static void phys_page_set(AddressSpaceDispatch *d,
> +                          target_phys_addr_t index, target_phys_addr_t nb,
>                            uint16_t leaf)
>  {
>      /* Wildly overreserve - it doesn't matter much. */
>      phys_map_node_reserve(3 * P_L2_LEVELS);
>
> -    phys_page_set_level(&phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
> +    phys_page_set_level(&d->phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
>  }
>
> -MemoryRegionSection *phys_page_find(target_phys_addr_t index)
> +MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, target_phys_addr_t index)
>  {
> -    PhysPageEntry lp = phys_map;
> +    PhysPageEntry lp = d->phys_map;
>      PhysPageEntry *p;
>      int i;
>      uint16_t s_index = phys_section_unassigned;
> @@ -1472,7 +1462,7 @@ void tb_invalidate_phys_addr(target_phys_addr_t addr)
>      ram_addr_t ram_addr;
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>      if (!(memory_region_is_ram(section->mr)
>            || (section->mr->rom_device && section->mr->readable))) {
>          return;
> @@ -2218,9 +2208,9 @@ static void destroy_l2_mapping(PhysPageEntry *lp, unsigned level)
>      lp->ptr = PHYS_MAP_NODE_NIL;
>  }
>
> -static void destroy_all_mappings(void)
> +static void destroy_all_mappings(AddressSpaceDispatch *d)
>  {
> -    destroy_l2_mapping(&phys_map, P_L2_LEVELS - 1);
> +    destroy_l2_mapping(&d->phys_map, P_L2_LEVELS - 1);
>      phys_map_nodes_reset();
>  }
>
> @@ -2240,12 +2230,12 @@ static void phys_sections_clear(void)
>      phys_sections_nb = 0;
>  }
>
> -static void register_subpage(MemoryRegionSection *section)
> +static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section)
>  {
>      subpage_t *subpage;
>      target_phys_addr_t base = section->offset_within_address_space
>          & TARGET_PAGE_MASK;
> -    MemoryRegionSection *existing = phys_page_find(base >> TARGET_PAGE_BITS);
> +    MemoryRegionSection *existing = phys_page_find(d, base >> TARGET_PAGE_BITS);
>      MemoryRegionSection subsection = {
>          .offset_within_address_space = base,
>          .size = TARGET_PAGE_SIZE,
> @@ -2257,7 +2247,7 @@ static void register_subpage(MemoryRegionSection *section)
>      if (!(existing->mr->subpage)) {
>          subpage = subpage_init(base);
>          subsection.mr = &subpage->iomem;
> -        phys_page_set(base >> TARGET_PAGE_BITS, 1,
> +        phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
>                        phys_section_add(&subsection));
>      } else {
>          subpage = container_of(existing->mr, subpage_t, iomem);
> @@ -2268,7 +2258,7 @@ static void register_subpage(MemoryRegionSection *section)
>  }
>
>
> -static void register_multipage(MemoryRegionSection *section)
> +static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *section)
>  {
>      target_phys_addr_t start_addr = section->offset_within_address_space;
>      ram_addr_t size = section->size;
> @@ -2278,13 +2268,13 @@ static void register_multipage(MemoryRegionSection *section)
>      assert(size);
>
>      addr = start_addr;
> -    phys_page_set(addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS,
> +    phys_page_set(d, addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS,
>                    section_index);
>  }
>
> -void cpu_register_physical_memory_log(MemoryRegionSection *section,
> -                                      bool readonly)
> +static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
>  {
> +    AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
>      MemoryRegionSection now = *section, remain = *section;
>
>      if ((now.offset_within_address_space & ~TARGET_PAGE_MASK)
> @@ -2292,7 +2282,7 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
>          now.size = MIN(TARGET_PAGE_ALIGN(now.offset_within_address_space)
>                         - now.offset_within_address_space,
>                         now.size);
> -        register_subpage(&now);
> +        register_subpage(d, &now);
>          remain.size -= now.size;
>          remain.offset_within_address_space += now.size;
>          remain.offset_within_region += now.size;
> @@ -2301,10 +2291,10 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
>          now = remain;
>          if (remain.offset_within_region & ~TARGET_PAGE_MASK) {
>              now.size = TARGET_PAGE_SIZE;
> -            register_subpage(&now);
> +            register_subpage(d, &now);
>          } else {
>              now.size &= TARGET_PAGE_MASK;
> -            register_multipage(&now);
> +            register_multipage(d, &now);
>          }
>          remain.size -= now.size;
>          remain.offset_within_address_space += now.size;
> @@ -2312,7 +2302,7 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
>      }
>      now = remain;
>      if (now.size) {
> -        register_subpage(&now);
> +        register_subpage(d, &now);
>      }
>  }
>
> @@ -3163,11 +3153,17 @@ static void io_mem_init(void)
>                            "watch", UINT64_MAX);
>  }
>
> +static void mem_begin(MemoryListener *listener)
> +{
> +    AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
> +
> +    destroy_all_mappings(d);
> +    d->phys_map.ptr = PHYS_MAP_NODE_NIL;
> +}
> +
>  static void core_begin(MemoryListener *listener)
>  {
> -    destroy_all_mappings();
>      phys_sections_clear();
> -    phys_map.ptr = PHYS_MAP_NODE_NIL;
>      phys_section_unassigned = dummy_section(&io_mem_unassigned);
>      phys_section_notdirty = dummy_section(&io_mem_notdirty);
>      phys_section_rom = dummy_section(&io_mem_rom);
> @@ -3186,18 +3182,6 @@ static void tcg_commit(MemoryListener *listener)
>      }
>  }
>
> -static void core_region_add(MemoryListener *listener,
> -                            MemoryRegionSection *section)
> -{
> -    cpu_register_physical_memory_log(section, section->readonly);
> -}
> -
> -static void core_region_nop(MemoryListener *listener,
> -                            MemoryRegionSection *section)
> -{
> -    cpu_register_physical_memory_log(section, section->readonly);
> -}
> -
>  static void core_log_global_start(MemoryListener *listener)
>  {
>      cpu_physical_memory_set_dirty_tracking(1);
> @@ -3229,11 +3213,9 @@ static void io_region_del(MemoryListener *listener,
>  static MemoryListener core_memory_listener = {
>      MEMORY_LISTENER_DEFAULT_OPS,
>      .begin = core_begin,
> -    .region_add = core_region_add,
> -    .region_nop = core_region_nop,
>      .log_global_start = core_log_global_start,
>      .log_global_stop = core_log_global_stop,
> -    .priority = 0,
> +    .priority = 1,
>  };
>
>  static MemoryListener io_memory_listener = {
> @@ -3248,6 +3230,22 @@ static void io_region_del(MemoryListener *listener,
>      .commit = tcg_commit,
>  };
>
> +void address_space_init_dispatch(AddressSpace *as)
> +{
> +    AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);
> +
> +    d->phys_map  = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
> +    d->listener = (MemoryListener) {
> +        MEMORY_LISTENER_DEFAULT_OPS,
> +        .begin = mem_begin,
> +        .region_add = mem_add,
> +        .region_nop = mem_add,
> +        .priority = 0,
> +    };
> +    as->dispatch = d;
> +    memory_listener_register(&d->listener, as);
> +}
> +
>  static void memory_map_init(void)
>  {
>      system_memory = g_malloc(sizeof(*system_memory));
> @@ -3319,9 +3317,11 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
>  }
>
>  #else
> -void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
> -                            int len, int is_write)
> +
> +void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf,
> +                      int len, bool is_write)

I'd make address_space_* use uint64_t instead of target_phys_addr_t
for the address. It may actually be buggy for 32 bit
target_phys_addr_t  and 64 bit DMA addresses, if such architectures
exist. Maybe memory.c could be made target independent one day.

>  {
> +    AddressSpaceDispatch *d = as->dispatch;
>      int l;
>      uint8_t *ptr;
>      uint32_t val;
> @@ -3333,7 +3333,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
>          l = (page + TARGET_PAGE_SIZE) - addr;
>          if (l > len)
>              l = len;
> -        section = phys_page_find(page >> TARGET_PAGE_BITS);
> +        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
>
>          if (is_write) {
>              if (!memory_region_is_ram(section->mr)) {
> @@ -3410,10 +3410,36 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
>      }
>  }
>
> +void address_space_write(AddressSpace *as, target_phys_addr_t addr,
> +                         const uint8_t *buf, int len)
> +{
> +    address_space_rw(as, addr, (uint8_t *)buf, len, true);
> +}
> +
> +/**
> + * address_space_read: read from an address space.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @buf: buffer with the data transferred
> + */
> +void address_space_read(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, int len)
> +{
> +    address_space_rw(as, addr, buf, len, false);
> +}
> +
> +
> +void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
> +                            int len, int is_write)
> +{
> +    return address_space_rw(&address_space_memory, addr, buf, len, is_write);
> +}
> +
>  /* used for ROM loading : can write in RAM and ROM */
>  void cpu_physical_memory_write_rom(target_phys_addr_t addr,
>                                     const uint8_t *buf, int len)
>  {
> +    AddressSpaceDispatch *d = address_space_memory.dispatch;
>      int l;
>      uint8_t *ptr;
>      target_phys_addr_t page;
> @@ -3424,7 +3450,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
>          l = (page + TARGET_PAGE_SIZE) - addr;
>          if (l > len)
>              l = len;
> -        section = phys_page_find(page >> TARGET_PAGE_BITS);
> +        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
>
>          if (!(memory_region_is_ram(section->mr) ||
>                memory_region_is_romd(section->mr))) {
> @@ -3504,10 +3530,12 @@ static void cpu_notify_map_clients(void)
>   * Use cpu_register_map_client() to know when retrying the map operation is
>   * likely to succeed.
>   */
> -void *cpu_physical_memory_map(target_phys_addr_t addr,
> -                              target_phys_addr_t *plen,
> -                              int is_write)
> +void *address_space_map(AddressSpace *as,
> +                        target_phys_addr_t addr,
> +                        target_phys_addr_t *plen,
> +                        bool is_write)
>  {
> +    AddressSpaceDispatch *d = as->dispatch;
>      target_phys_addr_t len = *plen;
>      target_phys_addr_t todo = 0;
>      int l;
> @@ -3522,7 +3550,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
>          l = (page + TARGET_PAGE_SIZE) - addr;
>          if (l > len)
>              l = len;
> -        section = phys_page_find(page >> TARGET_PAGE_BITS);
> +        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
>
>          if (!(memory_region_is_ram(section->mr) && !section->readonly)) {
>              if (todo || bounce.buffer) {
> @@ -3532,7 +3560,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
>              bounce.addr = addr;
>              bounce.len = l;
>              if (!is_write) {
> -                cpu_physical_memory_read(addr, bounce.buffer, l);
> +                address_space_read(as, addr, bounce.buffer, l);
>              }
>
>              *plen = l;
> @@ -3553,12 +3581,12 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
>      return ret;
>  }
>
> -/* Unmaps a memory region previously mapped by cpu_physical_memory_map().
> +/* Unmaps a memory region previously mapped by address_space_map().
>   * Will also mark the memory as dirty if is_write == 1.  access_len gives
>   * the amount of memory that was actually read or written by the caller.
>   */
> -void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
> -                               int is_write, target_phys_addr_t access_len)
> +void address_space_unmap(AddressSpace *as, void *buffer, target_phys_addr_t len,
> +                         int is_write, target_phys_addr_t access_len)
>  {
>      if (buffer != bounce.buffer) {
>          if (is_write) {
> @@ -3585,13 +3613,26 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
>          return;
>      }
>      if (is_write) {
> -        cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len);
> +        address_space_write(as, bounce.addr, bounce.buffer, access_len);
>      }
>      qemu_vfree(bounce.buffer);
>      bounce.buffer = NULL;
>      cpu_notify_map_clients();
>  }
>
> +void *cpu_physical_memory_map(target_phys_addr_t addr,
> +                              target_phys_addr_t *plen,
> +                              int is_write)
> +{
> +    return address_space_map(&address_space_memory, addr, plen, is_write);
> +}
> +
> +void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
> +                               int is_write, target_phys_addr_t access_len)
> +{
> +    return address_space_unmap(&address_space_memory, buffer, len, is_write, access_len);
> +}
> +
>  /* warning: addr must be aligned */
>  static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
>                                           enum device_endian endian)
> @@ -3600,7 +3641,7 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
>      uint32_t val;
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>
>      if (!(memory_region_is_ram(section->mr) ||
>            memory_region_is_romd(section->mr))) {
> @@ -3659,7 +3700,7 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
>      uint64_t val;
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>
>      if (!(memory_region_is_ram(section->mr) ||
>            memory_region_is_romd(section->mr))) {
> @@ -3726,7 +3767,7 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
>      uint64_t val;
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>
>      if (!(memory_region_is_ram(section->mr) ||
>            memory_region_is_romd(section->mr))) {
> @@ -3785,7 +3826,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
>      uint8_t *ptr;
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>
>      if (!memory_region_is_ram(section->mr) || section->readonly) {
>          addr = memory_region_section_addr(section, addr);
> @@ -3817,7 +3858,7 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
>      uint8_t *ptr;
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>
>      if (!memory_region_is_ram(section->mr) || section->readonly) {
>          addr = memory_region_section_addr(section, addr);
> @@ -3846,7 +3887,7 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
>      uint8_t *ptr;
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>
>      if (!memory_region_is_ram(section->mr) || section->readonly) {
>          addr = memory_region_section_addr(section, addr);
> @@ -3919,7 +3960,7 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
>      uint8_t *ptr;
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>
>      if (!memory_region_is_ram(section->mr) || section->readonly) {
>          addr = memory_region_section_addr(section, addr);
> @@ -4161,7 +4202,8 @@ bool cpu_physical_memory_is_io(target_phys_addr_t phys_addr)
>  {
>      MemoryRegionSection *section;
>
> -    section = phys_page_find(phys_addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch,
> +                             phys_addr >> TARGET_PAGE_BITS);
>
>      return !(memory_region_is_ram(section->mr) ||
>               memory_region_is_romd(section->mr));
> diff --git a/memory-internal.h b/memory-internal.h
> index 655f71f..a9d914e 100644
> --- a/memory-internal.h
> +++ b/memory-internal.h
> @@ -21,6 +21,26 @@
>
>  #ifndef CONFIG_USER_ONLY
>
> +typedef struct PhysPageEntry PhysPageEntry;
> +
> +struct PhysPageEntry {
> +    uint16_t is_leaf : 1;
> +     /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
> +    uint16_t ptr : 15;
> +};
> +
> +typedef struct AddressSpaceDispatch AddressSpaceDispatch;
> +
> +struct AddressSpaceDispatch {
> +    /* This is a multi-level map on the physical address space.
> +     * The bottom level has pointers to MemoryRegionSections.
> +     */
> +    PhysPageEntry phys_map;
> +    MemoryListener listener;
> +};
> +
> +void address_space_init_dispatch(AddressSpace *as);
> +
>  ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>                                     MemoryRegion *mr);
>  ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
> @@ -29,8 +49,6 @@ void qemu_ram_free_from_ptr(ram_addr_t addr);
>
>  struct MemoryRegion;
>  struct MemoryRegionSection;
> -void cpu_register_physical_memory_log(struct MemoryRegionSection *section,
> -                                      bool readonly);
>
>  void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
>  void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
> diff --git a/memory.c b/memory.c
> index f829d84..28a79ae 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1550,6 +1550,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
>      QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
>      as->name = NULL;
>      memory_region_transaction_commit();
> +    address_space_init_dispatch(as);
>  }
>
>  uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
> diff --git a/memory.h b/memory.h
> index 6115f48..84f7439 100644
> --- a/memory.h
> +++ b/memory.h
> @@ -169,6 +169,7 @@ struct AddressSpace {
>      struct FlatView *current_map;
>      int ioeventfd_nb;
>      struct MemoryRegionIoeventfd *ioeventfds;
> +    struct AddressSpaceDispatch *dispatch;
>      QTAILQ_ENTRY(AddressSpace) address_spaces_link;
>  };
>
> @@ -830,6 +831,67 @@ void mtree_info(fprintf_function mon_printf, void *f);
>   */
>  void address_space_init(AddressSpace *as, MemoryRegion *root);
>
> +/**
> + * address_space_rw: read from or write to an address space.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @buf: buffer with the data transferred
> + * @is_write: indicates the transfer direction
> + */
> +void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf,
> +                      int len, bool is_write);
> +
> +/**
> + * address_space_write: write to address space.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @buf: buffer with the data transferred
> + */
> +void address_space_write(AddressSpace *as, target_phys_addr_t addr,
> +                         const uint8_t *buf, int len);
> +
> +/**
> + * address_space_read: read from an address space.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @buf: buffer with the data transferred
> + */
> +void address_space_read(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, int len);
> +
> +/* address_space_map: map a physical memory region into a host virtual address
> + *
> + * May map a subset of the requested range, given by and returned in @plen.
> + * May return %NULL if resources needed to perform the mapping are exhausted.
> + * Use only for reads OR writes - not for read-modify-write operations.
> + * Use cpu_register_map_client() to know when retrying the map operation is
> + * likely to succeed.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @plen: pointer to length of buffer; updated on return
> + * @is_write: indicates the transfer direction
> + */
> +void *address_space_map(AddressSpace *as, target_phys_addr_t addr,
> +                        target_phys_addr_t *plen, bool is_write);
> +
> +/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
> + *
> + * Will also mark the memory as dirty if @is_write == %true.  @access_len gives
> + * the amount of memory that was actually read or written by the caller.
> + *
> + * @as: #AddressSpace used
> + * @addr: address within that address space
> + * @len: buffer length as returned by address_space_map()
> + * @access_len: amount of data actually transferred
> + * @is_write: indicates the transfer direction
> + */
> +void address_space_unmap(AddressSpace *as, void *buffer, target_phys_addr_t len,
> +                         int is_write, target_phys_addr_t access_len);
> +
> +
>  #endif
>
>  #endif
> --
> 1.7.12
>

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

* Re: [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (21 preceding siblings ...)
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 22/22] pci: honor PCI_COMMAND_MASTER Avi Kivity
@ 2012-10-03 20:26 ` Blue Swirl
  2012-10-04 10:18   ` Avi Kivity
  2012-10-04  6:41 ` Avi Kivity
  2012-10-04  8:13 ` Paolo Bonzini
  24 siblings, 1 reply; 70+ messages in thread
From: Blue Swirl @ 2012-10-03 20:26 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On Wed, Oct 3, 2012 at 4:03 PM, Avi Kivity <avi@redhat.com> wrote:
> 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.

Excellent patches with high cleanup potential.

>
> Avi Kivity (22):
>   memory: rename 'exec-obsolete.h'
>   vhost: use MemoryListener filtering to only monitor RAM address space
>   kvm: use separate MemoryListeners for memory and I/O
>   xen_pt: use separate MemoryListeners for memory and I/O
>   memory: prepare AddressSpace for exporting
>   memory: export AddressSpace
>   memory: maintain a list of address spaces
>   memory: provide defaults for MemoryListener operations
>   memory: use new MEMORY_LISTENER_DEFAULT_OPS
>   vfio: use new MEMORY_LISTENER_DEFAULT_OPS
>   xen_pt: use new MEMORY_LISTENER_DEFAULT_OPS
>   kvm: use new MEMORY_LISTENER_DEFAULT_OPS
>   xen: use new MEMORY_LISTENER_DEFAULT_OPS
>   memory: manage coalesced mmio via a MemoryListener
>   memory: move address_space_memory and address_space_io out of memory
>     core
>   memory: move tcg flush into a tcg memory listener
>   memory: use AddressSpace for MemoryListener filtering
>   s390: avoid reaching into memory core internals
>   memory: per-AddressSpace dispatch
>   dma: make dma access its own address space
>   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                               | 312 ++++++++++++++---------------------
>  hw/Makefile.objs                     |   5 +-
>  hw/pci.c                             |  19 ++-
>  hw/pci.h                             |   2 +
>  hw/spapr_iommu.c                     |   3 +-
>  hw/vfio_pci.c                        |  33 +---
>  hw/vhost.c                           |   5 +-
>  hw/xen_pt.c                          |  49 +++---
>  hw/xen_pt.h                          |   1 +
>  kvm-all.c                            | 107 +++++-------
>  kvm-stub.c                           |  10 --
>  kvm.h                                |   2 -
>  exec-obsolete.h => memory-internal.h |  30 +++-
>  memory.c                             | 158 +++++++++++-------
>  memory.h                             | 122 +++++++++++++-
>  target-s390x/misc_helper.c           |   2 +-
>  xen-all.c                            |  45 +----
>  22 files changed, 487 insertions(+), 476 deletions(-)
>  rename exec-obsolete.h => memory-internal.h (87%)
>
> --
> 1.7.12
>

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

* Re: [Qemu-devel] [RFC v1 03/22] kvm: use separate MemoryListeners for memory and I/O
  2012-10-03 20:16   ` Blue Swirl
@ 2012-10-04  6:33     ` Avi Kivity
  2012-10-04 16:44       ` Blue Swirl
  0 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-04  6:33 UTC (permalink / raw)
  To: Blue Swirl
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On 10/03/2012 10:16 PM, Blue Swirl wrote:
> > +static MemoryListener kvm_io_listener = {
>
> const
>

There is a list link field in there.  It's a mixed data/ops structure
(perhaps we should make it a traditional ->ops-> pointer).

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-03 20:24   ` Blue Swirl
@ 2012-10-04  6:38     ` Avi Kivity
  2012-10-04  8:47       ` Peter Maydell
  2012-10-04 17:13       ` Blue Swirl
  0 siblings, 2 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-04  6:38 UTC (permalink / raw)
  To: Blue Swirl
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On 10/03/2012 10:24 PM, Blue Swirl wrote:
> >
> >  #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)
>
> I'd make address_space_* use uint64_t instead of target_phys_addr_t
> for the address. It may actually be buggy for 32 bit
> target_phys_addr_t  and 64 bit DMA addresses, if such architectures
> exist. Maybe memory.c could be made target independent one day.

We can make target_phys_addr_t 64 bit unconditionally.  The fraction of
deployments where both host and guest are 32 bits is dropping, and I
doubt the performance drop is noticable.

We were also planning to rename target_phys_addt_t to hw_addr.

But both of those are for another patch.  For now, AddressSpace follows
MemoryRegion, it's just a small abstraction on top.


-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

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

* Re: [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (22 preceding siblings ...)
  2012-10-03 20:26 ` [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Blue Swirl
@ 2012-10-04  6:41 ` Avi Kivity
  2012-10-04  8:13 ` Paolo Bonzini
  24 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-04  6:41 UTC (permalink / raw)
  To: qemu-devel, Anthony Liguori, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl
  Cc: Alex Williamson, Stefano Stabellini

Adding missing cc's: there are minor changes to vfio and xen here,
please review and test.

On 10/03/2012 06:03 PM, Avi Kivity wrote:
> 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.
>
> Avi Kivity (22):
>   memory: rename 'exec-obsolete.h'
>   vhost: use MemoryListener filtering to only monitor RAM address space
>   kvm: use separate MemoryListeners for memory and I/O
>   xen_pt: use separate MemoryListeners for memory and I/O
>   memory: prepare AddressSpace for exporting
>   memory: export AddressSpace
>   memory: maintain a list of address spaces
>   memory: provide defaults for MemoryListener operations
>   memory: use new MEMORY_LISTENER_DEFAULT_OPS
>   vfio: use new MEMORY_LISTENER_DEFAULT_OPS
>   xen_pt: use new MEMORY_LISTENER_DEFAULT_OPS
>   kvm: use new MEMORY_LISTENER_DEFAULT_OPS
>   xen: use new MEMORY_LISTENER_DEFAULT_OPS
>   memory: manage coalesced mmio via a MemoryListener
>   memory: move address_space_memory and address_space_io out of memory
>     core
>   memory: move tcg flush into a tcg memory listener
>   memory: use AddressSpace for MemoryListener filtering
>   s390: avoid reaching into memory core internals
>   memory: per-AddressSpace dispatch
>   dma: make dma access its own address space
>   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                               | 312 ++++++++++++++---------------------
>  hw/Makefile.objs                     |   5 +-
>  hw/pci.c                             |  19 ++-
>  hw/pci.h                             |   2 +
>  hw/spapr_iommu.c                     |   3 +-
>  hw/vfio_pci.c                        |  33 +---
>  hw/vhost.c                           |   5 +-
>  hw/xen_pt.c                          |  49 +++---
>  hw/xen_pt.h                          |   1 +
>  kvm-all.c                            | 107 +++++-------
>  kvm-stub.c                           |  10 --
>  kvm.h                                |   2 -
>  exec-obsolete.h => memory-internal.h |  30 +++-
>  memory.c                             | 158 +++++++++++-------
>  memory.h                             | 122 +++++++++++++-
>  target-s390x/misc_helper.c           |   2 +-
>  xen-all.c                            |  45 +----
>  22 files changed, 487 insertions(+), 476 deletions(-)
>  rename exec-obsolete.h => memory-internal.h (87%)
>


-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

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

* Re: [Qemu-devel] [RFC v1 18/22] s390: avoid reaching into memory core internals
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 18/22] s390: avoid reaching into memory core internals Avi Kivity
@ 2012-10-04  8:12   ` Christian Borntraeger
  0 siblings, 0 replies; 70+ messages in thread
From: Christian Borntraeger @ 2012-10-04  8:12 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Alexander Graf, Heinz Graalfs, Michael S. Tsirkin, qemu-devel,
	liu ping fan, Blue Swirl, Jens Freimann, Anthony Liguori,
	Paolo Bonzini

On 03/10/12 18:04, Avi Kivity wrote:
> use cpu_physical_memory_is_io() instead.
> 
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  target-s390x/misc_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
> index e9b3cae..2da4c90 100644
> --- a/target-s390x/misc_helper.c
> +++ b/target-s390x/misc_helper.c
> @@ -81,7 +81,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) {
> 

You can then probably also remove the #include "cputlb.h"

As a heads up: We have some patches pending that move that code. 
see https://lists.gnu.org/archive/html/qemu-devel/2012-10/msg00121.html

So let us know if we should refresh the patch - otherwise we will let
that be resolved by the person that merges the commit. (will be a merge
conflict)

Christian

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

* Re: [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API
  2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
                   ` (23 preceding siblings ...)
  2012-10-04  6:41 ` Avi Kivity
@ 2012-10-04  8:13 ` Paolo Bonzini
  2012-10-04 14:16   ` Anthony Liguori
  24 siblings, 1 reply; 70+ messages in thread
From: Paolo Bonzini @ 2012-10-04  8:13 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Blue Swirl, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

Il 03/10/2012 18:03, Avi Kivity ha scritto:
> 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.

Very nice, IMHO patches 1-18 should get in soon.  They are a useful
cleanup on their own.

Paolo

> Avi Kivity (22):
>   memory: rename 'exec-obsolete.h'
>   vhost: use MemoryListener filtering to only monitor RAM address space
>   kvm: use separate MemoryListeners for memory and I/O
>   xen_pt: use separate MemoryListeners for memory and I/O
>   memory: prepare AddressSpace for exporting
>   memory: export AddressSpace
>   memory: maintain a list of address spaces
>   memory: provide defaults for MemoryListener operations
>   memory: use new MEMORY_LISTENER_DEFAULT_OPS
>   vfio: use new MEMORY_LISTENER_DEFAULT_OPS
>   xen_pt: use new MEMORY_LISTENER_DEFAULT_OPS
>   kvm: use new MEMORY_LISTENER_DEFAULT_OPS
>   xen: use new MEMORY_LISTENER_DEFAULT_OPS
>   memory: manage coalesced mmio via a MemoryListener
>   memory: move address_space_memory and address_space_io out of memory
>     core
>   memory: move tcg flush into a tcg memory listener
>   memory: use AddressSpace for MemoryListener filtering
>   s390: avoid reaching into memory core internals
>   memory: per-AddressSpace dispatch
>   dma: make dma access its own address space
>   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                               | 312 ++++++++++++++---------------------
>  hw/Makefile.objs                     |   5 +-
>  hw/pci.c                             |  19 ++-
>  hw/pci.h                             |   2 +
>  hw/spapr_iommu.c                     |   3 +-
>  hw/vfio_pci.c                        |  33 +---
>  hw/vhost.c                           |   5 +-
>  hw/xen_pt.c                          |  49 +++---
>  hw/xen_pt.h                          |   1 +
>  kvm-all.c                            | 107 +++++-------
>  kvm-stub.c                           |  10 --
>  kvm.h                                |   2 -
>  exec-obsolete.h => memory-internal.h |  30 +++-
>  memory.c                             | 158 +++++++++++-------
>  memory.h                             | 122 +++++++++++++-
>  target-s390x/misc_helper.c           |   2 +-
>  xen-all.c                            |  45 +----
>  22 files changed, 487 insertions(+), 476 deletions(-)
>  rename exec-obsolete.h => memory-internal.h (87%)
> 

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04  6:38     ` Avi Kivity
@ 2012-10-04  8:47       ` Peter Maydell
  2012-10-04 10:15         ` Avi Kivity
  2012-10-04 17:13       ` Blue Swirl
  1 sibling, 1 reply; 70+ messages in thread
From: Peter Maydell @ 2012-10-04  8:47 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Michael S. Tsirkin, liu ping fan, qemu-devel, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 4 October 2012 07:38, Avi Kivity <avi@redhat.com> wrote:
> On 10/03/2012 10:24 PM, Blue Swirl wrote:
>> >
>> >  #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)
>>
>> I'd make address_space_* use uint64_t instead of target_phys_addr_t
>> for the address. It may actually be buggy for 32 bit
>> target_phys_addr_t  and 64 bit DMA addresses, if such architectures
>> exist. Maybe memory.c could be made target independent one day.

I thought target_phys_addr_t was supposed to be "widest necessary
address", so an architecture with 64 bit DMA addresses should be
implemented with 64 bit target_phys_addr_t...

> We can make target_phys_addr_t 64 bit unconditionally.  The fraction of
> deployments where both host and guest are 32 bits is dropping, and I
> doubt the performance drop is noticable.

I benchmarked it on ARM when I switched ARM to always 64 bit physaddrs;
it was just about measurable (maybe half a percent or so) but not
significant (we don't use this type in the fast path for memory
accesses, only in the slow/IO path).

I'd favour just moving everything to 64 bits (the remaining
32 bit targets are: cris, lm32, m68k, microblaze, or32, sh4, unicore32,
xtensa). However it does require some review of devices to check that
they're not using target_phys_addr_t when they meant uint32_t [eg
in registers for DMA devices] or relying on 32 bit wraparound.

-- PMM

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04  8:47       ` Peter Maydell
@ 2012-10-04 10:15         ` Avi Kivity
  2012-10-04 10:29           ` Peter Maydell
  0 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 10:15 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Michael S. Tsirkin, liu ping fan, qemu-devel, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 10/04/2012 10:47 AM, Peter Maydell wrote:
>>> I'd make address_space_* use uint64_t instead of target_phys_addr_t
>>> for the address. It may actually be buggy for 32 bit
>>> target_phys_addr_t  and 64 bit DMA addresses, if such architectures
>>> exist. Maybe memory.c could be made target independent one day.
> 
> I thought target_phys_addr_t was supposed to be "widest necessary
> address", so an architecture with 64 bit DMA addresses should be
> implemented with 64 bit target_phys_addr_t...

Yes.  Since even before this patchset all DMA went through the memory
API (and before the memory API, through cpu_register_physical_memory),
this case was already broken.

> 
>> We can make target_phys_addr_t 64 bit unconditionally.  The fraction of
>> deployments where both host and guest are 32 bits is dropping, and I
>> doubt the performance drop is noticable.
> 
> I benchmarked it on ARM when I switched ARM to always 64 bit physaddrs;
> it was just about measurable (maybe half a percent or so) but not
> significant (we don't use this type in the fast path for memory
> accesses, only in the slow/IO path).
> 
> I'd favour just moving everything to 64 bits (the remaining
> 32 bit targets are: cris, lm32, m68k, microblaze, or32, sh4, unicore32,
> xtensa). However it does require some review of devices to check that
> they're not using target_phys_addr_t when they meant uint32_t [eg
> in registers for DMA devices] or relying on 32 bit wraparound.

I posted a patch.  I did no review, the cost/benefit tradeoff is
horrible IMO, especially with me not knowing the details.  If something
breaks, git bisect will save the day.

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

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

* Re: [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering
  2012-10-03 20:16   ` Blue Swirl
@ 2012-10-04 10:17     ` Avi Kivity
  2012-10-04 16:57       ` Blue Swirl
  0 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 10:17 UTC (permalink / raw)
  To: Blue Swirl
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On 10/03/2012 10:16 PM, Blue Swirl wrote:
>> @@ -141,7 +141,7 @@ static bool memory_listener_match(MemoryListener *listener,
>>  #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
>>      MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) {       \
>>          .mr = (fr)->mr,                                                 \
>> -        .address_space = (as)->root,                                    \
>> +        .address_space = (as),                                          \
> 
> Maybe remove parenthesis.

I prefer to keep it for consistency and defensiveness, unless you insist.


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

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

* Re: [Qemu-devel] [RFC v1 07/22] memory: maintain a list of address spaces
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 07/22] memory: maintain a list of address spaces Avi Kivity
@ 2012-10-04 10:17   ` Gleb Natapov
  2012-10-04 10:19     ` Avi Kivity
  2012-10-04 14:03   ` Anthony Liguori
  1 sibling, 1 reply; 70+ messages in thread
From: Gleb Natapov @ 2012-10-04 10:17 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Michael S. Tsirkin, qemu-devel, liu ping fan, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On Wed, Oct 03, 2012 at 06:03:50PM +0200, Avi Kivity wrote:
> 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 but masters.
------------------------------------^ bus?

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

--
			Gleb.

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

* Re: [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API
  2012-10-03 20:26 ` [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Blue Swirl
@ 2012-10-04 10:18   ` Avi Kivity
  0 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 10:18 UTC (permalink / raw)
  To: Blue Swirl
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On 10/03/2012 10:26 PM, Blue Swirl wrote:
> On Wed, Oct 3, 2012 at 4:03 PM, Avi Kivity <avi@redhat.com> wrote:
>> 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.
> 
> Excellent patches with high cleanup potential.

Thanks.  The next steps are memory_region_init_iommu() and the
replacement of DMAContext with AddressSpace.


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

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

* Re: [Qemu-devel] [RFC v1 07/22] memory: maintain a list of address spaces
  2012-10-04 10:17   ` Gleb Natapov
@ 2012-10-04 10:19     ` Avi Kivity
  0 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 10:19 UTC (permalink / raw)
  To: Gleb Natapov
  Cc: Michael S. Tsirkin, qemu-devel, liu ping fan, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 10/04/2012 12:17 PM, Gleb Natapov wrote:
> On Wed, Oct 03, 2012 at 06:03:50PM +0200, Avi Kivity wrote:
>> 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 but masters.
> ------------------------------------^ bus?

Fixed.


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

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 10:15         ` Avi Kivity
@ 2012-10-04 10:29           ` Peter Maydell
  2012-10-04 10:30             ` Avi Kivity
  0 siblings, 1 reply; 70+ messages in thread
From: Peter Maydell @ 2012-10-04 10:29 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Michael S. Tsirkin, liu ping fan, qemu-devel, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 4 October 2012 11:15, Avi Kivity <avi@redhat.com> wrote:
> On 10/04/2012 10:47 AM, Peter Maydell wrote:
>> I'd favour just moving everything to 64 bits (the remaining
>> 32 bit targets are: cris, lm32, m68k, microblaze, or32, sh4, unicore32,
>> xtensa). However it does require some review of devices to check that
>> they're not using target_phys_addr_t when they meant uint32_t [eg
>> in registers for DMA devices] or relying on 32 bit wraparound.
>
> I posted a patch.  I did no review, the cost/benefit tradeoff is
> horrible IMO, especially with me not knowing the details.  If something
> breaks, git bisect will save the day.

It might be nice to cc the maintainers of the affected target archs
and suggest that they at least do a quick smoke test :-)

-- PMM

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 10:29           ` Peter Maydell
@ 2012-10-04 10:30             ` Avi Kivity
  0 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 10:30 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Michael S. Tsirkin, liu ping fan, qemu-devel, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 10/04/2012 12:29 PM, Peter Maydell wrote:
> On 4 October 2012 11:15, Avi Kivity <avi@redhat.com> wrote:
>> On 10/04/2012 10:47 AM, Peter Maydell wrote:
>>> I'd favour just moving everything to 64 bits (the remaining
>>> 32 bit targets are: cris, lm32, m68k, microblaze, or32, sh4, unicore32,
>>> xtensa). However it does require some review of devices to check that
>>> they're not using target_phys_addr_t when they meant uint32_t [eg
>>> in registers for DMA devices] or relying on 32 bit wraparound.
>>
>> I posted a patch.  I did no review, the cost/benefit tradeoff is
>> horrible IMO, especially with me not knowing the details.  If something
>> breaks, git bisect will save the day.
> 
> It might be nice to cc the maintainers of the affected target archs
> and suggest that they at least do a quick smoke test :-)

Yes, will do.


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

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

* Re: [Qemu-devel] [RFC v1 01/22] memory: rename 'exec-obsolete.h'
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 01/22] memory: rename 'exec-obsolete.h' Avi Kivity
@ 2012-10-04 13:58   ` Anthony Liguori
  0 siblings, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 13:58 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> 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.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

> ---
>  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	[flat|nested] 70+ messages in thread

* Re: [Qemu-devel] [RFC v1 05/22] memory: prepare AddressSpace for exporting
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 05/22] memory: prepare AddressSpace for exporting Avi Kivity
@ 2012-10-04 14:01   ` Anthony Liguori
  0 siblings, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14: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:

> 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.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

> ---
>  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	[flat|nested] 70+ messages in thread

* Re: [Qemu-devel] [RFC v1 06/22] memory: export AddressSpace
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 06/22] memory: export AddressSpace Avi Kivity
@ 2012-10-04 14:02   ` Anthony Liguori
  0 siblings, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:02 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> The DMA API will use an AddressSpace to differentiate among different
> initiators.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

> ---
>  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	[flat|nested] 70+ messages in thread

* Re: [Qemu-devel] [RFC v1 07/22] memory: maintain a list of address spaces
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 07/22] memory: maintain a list of address spaces Avi Kivity
  2012-10-04 10:17   ` Gleb Natapov
@ 2012-10-04 14:03   ` Anthony Liguori
  1 sibling, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:03 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> 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 but masters.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

> ---
>  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	[flat|nested] 70+ messages in thread

* Re: [Qemu-devel] [RFC v1 08/22] memory: provide defaults for MemoryListener operations
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 08/22] memory: provide defaults for MemoryListener operations Avi Kivity
@ 2012-10-04 14:05   ` Anthony Liguori
  2012-10-04 14:29     ` Avi Kivity
  0 siblings, 1 reply; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:05 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> Many listeners don't need to respond to all MemoryListener callbacks;
> provide suitable defaults instead.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  memory.c | 15 +++++++++++++++
>  memory.h | 21 +++++++++++++++++++++
>  2 files changed, 36 insertions(+)
>
> diff --git a/memory.c b/memory.c
> index b58b97c..efefcb8 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1514,6 +1514,21 @@ void memory_listener_unregister(MemoryListener *listener)
>      QTAILQ_REMOVE(&memory_listeners, listener, link);
>  }
>  
> +void memory_listener_default_global(MemoryListener *listener)
> +{
> +}
> +
> +void memory_listener_default_section(MemoryListener *listener,
> +                                     MemoryRegionSection *section)
> +{
> +}
> +
> +void memory_listener_default_eventfd(MemoryListener *listener,
> +                                     MemoryRegionSection *section,
> +                                     bool match_data, uint64_t data, EventNotifier *e)
> +{
> +}
> +
>  void address_space_init(AddressSpace *as, MemoryRegion *root)
>  {
>      memory_region_transaction_begin();
> diff --git a/memory.h b/memory.h
> index 46bc5e1..0ef95cb 100644
> --- a/memory.h
> +++ b/memory.h
> @@ -223,6 +223,27 @@ struct MemoryListener {
>      QTAILQ_ENTRY(MemoryListener) link;
>  };
>  
> +#define MEMORY_LISTENER_DEFAULT_OPS                         \
> +    .begin = memory_listener_default_global,                \
> +    .commit = memory_listener_default_global,               \
> +    .region_add = memory_listener_default_section,          \
> +    .region_del = memory_listener_default_section,          \
> +    .region_nop = memory_listener_default_section,          \
> +    .log_start = memory_listener_default_section,           \
> +    .log_stop = memory_listener_default_section,            \
> +    .log_sync = memory_listener_default_section,            \
> +    .log_global_start = memory_listener_default_global,     \
> +    .log_global_stop = memory_listener_default_global,      \
> +    .eventfd_add = memory_listener_default_eventfd,         \
> +    .eventfd_del = memory_listener_default_eventfd          \
> +
> +void memory_listener_default_global(MemoryListener *listener);
> +void memory_listener_default_section(MemoryListener *listener,
> +                                     MemoryRegionSection *section);
> +void memory_listener_default_eventfd(MemoryListener *listener,
> +                                     MemoryRegionSection *section,
> +                                     bool match_data, uint64_t data, EventNotifier *e);
> +
>  /**
>   * memory_region_init: Initialize a memory region
>   *

I think it'd be nicer to check for NULL when invoking the functions in
the memory core.

Then you avoid the exported stub functions entirely.

Regards,

Anthony Liguori

> -- 
> 1.7.12

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

* Re: [Qemu-devel] [RFC v1 14/22] memory: manage coalesced mmio via a MemoryListener
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 14/22] memory: manage coalesced mmio via a MemoryListener Avi Kivity
@ 2012-10-04 14:08   ` Anthony Liguori
  2012-10-04 14:33     ` Avi Kivity
  0 siblings, 1 reply; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:08 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> Instead of calling a global function on coalesced mmio changes, which
> routes the call to kvm if enabled, add coalesced mmio hooks to
> MemoryListener and make kvm use that instead.
>
> The motivation is support for multiple address spaces (which means we
> we need to filter the call on the right address space) but the result
> is cleaner as well.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  exec.c     | 13 -------------
>  kvm-all.c  | 20 ++++++++++----------
>  kvm-stub.c | 10 ----------
>  kvm.h      |  2 --
>  memory.c   | 24 ++++++++++++++++++++----
>  memory.h   | 12 +++++++++++-
>  6 files changed, 41 insertions(+), 40 deletions(-)
>
> diff --git a/exec.c b/exec.c
> index 1fd6a10..51a32e7 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -2313,19 +2313,6 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
>      }
>  }
>  
> -
> -void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
> -{
> -    if (kvm_enabled())
> -        kvm_coalesce_mmio_region(addr, size);
> -}
> -
> -void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
> -{
> -    if (kvm_enabled())
> -        kvm_uncoalesce_mmio_region(addr, size);
> -}
> -
>  void qemu_flush_coalesced_mmio_buffer(void)
>  {
>      if (kvm_enabled())
> diff --git a/kvm-all.c b/kvm-all.c
> index 5e9215d..25ca202 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -454,9 +454,10 @@ static int kvm_physical_sync_dirty_bitmap(MemoryRegionSection *section)
>      return ret;
>  }
>  
> -int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
> +static void kvm_coalesce_mmio_region(MemoryListener *listener,
> +                                     MemoryRegionSection *secion,
> +                                     target_phys_addr_t start, ram_addr_t size)
>  {
> -    int ret = -ENOSYS;
>      KVMState *s = kvm_state;
>  
>      if (s->coalesced_mmio) {
> @@ -466,15 +467,14 @@ int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
>          zone.size = size;
>          zone.pad = 0;
>  
> -        ret = kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone);
> +        (void)kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone);

g_assert on error instead of ignoring it.

>      }
> -
> -    return ret;
>  }
>  
> -int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
> +static void kvm_uncoalesce_mmio_region(MemoryListener *listener,
> +                                       MemoryRegionSection *secion,
> +                                       target_phys_addr_t start, ram_addr_t size)
>  {
> -    int ret = -ENOSYS;
>      KVMState *s = kvm_state;
>  
>      if (s->coalesced_mmio) {
> @@ -484,10 +484,8 @@ int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
>          zone.size = size;
>          zone.pad = 0;
>  
> -        ret = kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone);
> +        (void)kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone);
>      }
> -
> -    return ret;
>  }
>  
>  int kvm_check_extension(KVMState *s, unsigned int extension)
> @@ -818,6 +816,8 @@ static void kvm_io_ioeventfd_del(MemoryListener *listener,
>      .log_global_stop = kvm_log_global_stop,
>      .eventfd_add = kvm_mem_ioeventfd_add,
>      .eventfd_del = kvm_mem_ioeventfd_del,
> +    .coalesced_mmio_add = kvm_coalesce_mmio_region,
> +    .coalesced_mmio_del = kvm_uncoalesce_mmio_region,
>      .priority = 10,
>  };
>  
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 3c52eb5..a3455e2 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -29,16 +29,6 @@ int kvm_init_vcpu(CPUArchState *env)
>      return -ENOSYS;
>  }
>  
> -int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
> -{
> -    return -ENOSYS;
> -}
> -
> -int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
> -{
> -    return -ENOSYS;
> -}
> -
>  int kvm_init(void)
>  {
>      return -ENOSYS;
> diff --git a/kvm.h b/kvm.h
> index dea2998..eefcb49 100644
> --- a/kvm.h
> +++ b/kvm.h
> @@ -129,8 +129,6 @@ void *kvm_vmalloc(ram_addr_t size);
>  void *kvm_arch_vmalloc(ram_addr_t size);
>  void kvm_setup_guest_memory(void *start, size_t size);
>  
> -int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
> -int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
>  void kvm_flush_coalesced_mmio_buffer(void);
>  #endif
>  
> diff --git a/memory.c b/memory.c
> index efefcb8..eb75349 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1130,11 +1130,19 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
>      FlatRange *fr;
>      CoalescedMemoryRange *cmr;
>      AddrRange tmp;
> +    MemoryRegionSection section;
>  
>      FOR_EACH_FLAT_RANGE(fr, as->current_map) {
>          if (fr->mr == mr) {
> -            qemu_unregister_coalesced_mmio(int128_get64(fr->addr.start),
> -                                           int128_get64(fr->addr.size));
> +            section = (MemoryRegionSection) {
> +                .address_space = as->root,
> +                .offset_within_address_space = int128_get64(fr->addr.start),
> +                .size = int128_get64(fr->addr.size),
> +            };

I think this is a bit too clever.  You can move the definition of
section into this block with a zero initializer, and then just set the
fields directly.  You'll end up losing 2 lines of code in the process
too.

Regards,

Anthony Liguori

> +
> +            MEMORY_LISTENER_CALL(coalesced_mmio_del, Reverse, &section,
> +                                 int128_get64(fr->addr.start),
> +                                 int128_get64(fr->addr.size));
>              QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
>                  tmp = addrrange_shift(cmr->addr,
>                                        int128_sub(fr->addr.start,
> @@ -1143,8 +1151,9 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
>                      continue;
>                  }
>                  tmp = addrrange_intersection(tmp, fr->addr);
> -                qemu_register_coalesced_mmio(int128_get64(tmp.start),
> -                                             int128_get64(tmp.size));
> +                MEMORY_LISTENER_CALL(coalesced_mmio_add, Forward, &section,
> +                                     int128_get64(tmp.start),
> +                                     int128_get64(tmp.size));
>              }
>          }
>      }
> @@ -1529,6 +1538,13 @@ void memory_listener_default_eventfd(MemoryListener *listener,
>  {
>  }
>  
> +void memory_listener_default_coalesced_mmio(MemoryListener *listener,
> +                                            MemoryRegionSection *section,
> +                                            target_phys_addr_t addr,
> +                                            target_phys_addr_t len)
> +{
> +}
> +
>  void address_space_init(AddressSpace *as, MemoryRegion *root)
>  {
>      memory_region_transaction_begin();
> diff --git a/memory.h b/memory.h
> index 0ef95cb..5f50bce 100644
> --- a/memory.h
> +++ b/memory.h
> @@ -217,6 +217,10 @@ struct MemoryListener {
>                          bool match_data, uint64_t data, EventNotifier *e);
>      void (*eventfd_del)(MemoryListener *listener, MemoryRegionSection *section,
>                          bool match_data, uint64_t data, EventNotifier *e);
> +    void (*coalesced_mmio_add)(MemoryListener *listener, MemoryRegionSection *section,
> +                               target_phys_addr_t addr, target_phys_addr_t len);
> +    void (*coalesced_mmio_del)(MemoryListener *listener, MemoryRegionSection *section,
> +                               target_phys_addr_t addr, target_phys_addr_t len);
>      /* Lower = earlier (during add), later (during del) */
>      unsigned priority;
>      MemoryRegion *address_space_filter;
> @@ -235,7 +239,9 @@ struct MemoryListener {
>      .log_global_start = memory_listener_default_global,     \
>      .log_global_stop = memory_listener_default_global,      \
>      .eventfd_add = memory_listener_default_eventfd,         \
> -    .eventfd_del = memory_listener_default_eventfd          \
> +    .eventfd_del = memory_listener_default_eventfd,         \
> +    .coalesced_mmio_add = memory_listener_default_coalesced_mmio,  \
> +    .coalesced_mmio_del = memory_listener_default_coalesced_mmio   \
>  
>  void memory_listener_default_global(MemoryListener *listener);
>  void memory_listener_default_section(MemoryListener *listener,
> @@ -243,6 +249,10 @@ void memory_listener_default_section(MemoryListener *listener,
>  void memory_listener_default_eventfd(MemoryListener *listener,
>                                       MemoryRegionSection *section,
>                                       bool match_data, uint64_t data, EventNotifier *e);
> +void memory_listener_default_coalesced_mmio(MemoryListener *listener,
> +                                            MemoryRegionSection *section,
> +                                            target_phys_addr_t addr,
> +                                            target_phys_addr_t len);
>  
>  /**
>   * memory_region_init: Initialize a memory region
> -- 
> 1.7.12

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

* Re: [Qemu-devel] [RFC v1 15/22] memory: move address_space_memory and address_space_io out of memory core
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 15/22] memory: move address_space_memory and address_space_io out of memory core Avi Kivity
@ 2012-10-04 14:08   ` Anthony Liguori
  0 siblings, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:08 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> With this change, memory.c no longer knows anything about special address
> spaces, so it is prepared for AddressSpace based DMA.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

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

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

* Re: [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering Avi Kivity
  2012-10-03 20:16   ` Blue Swirl
@ 2012-10-04 14:09   ` Anthony Liguori
  1 sibling, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:09 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> Using the AddressSpace type reduces confusion, as you can't accidentally
> supply the MemoryRegion you're interested in.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

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

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch Avi Kivity
  2012-10-03 20:24   ` Blue Swirl
@ 2012-10-04 14:13   ` Anthony Liguori
  2012-10-04 14:43     ` Avi Kivity
  1 sibling, 1 reply; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:13 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> Currently we use a global radix tree to dispatch memory access.  This only
> works with a single address space; to support multiple address spaces we
> make the radix tree a member of AddressSpace (via an intermediate structure
> AddressSpaceDispatch to avoid exposing too many internals).
>
> A side effect is that address_space_io also gains a dispatch table.  When
> we remove all the pre-memory-API I/O registrations, we can use that for
> dispatching I/O and get rid of the original I/O dispatch.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  cputlb.c          |   3 +-
>  cputlb.h          |   3 +-
>  exec.c            | 176 +++++++++++++++++++++++++++++++++---------------------
>  memory-internal.h |  22 ++++++-
>  memory.c          |   1 +
>  memory.h          |  62 +++++++++++++++++++
>  6 files changed, 196 insertions(+), 71 deletions(-)
>
> diff --git a/cputlb.c b/cputlb.c
> index 0627f32..9027557 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -21,6 +21,7 @@
>  #include "cpu.h"
>  #include "exec-all.h"
>  #include "memory.h"
> +#include "exec-memory.h"
>  
>  #include "cputlb.h"
>  
> @@ -251,7 +252,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
>      if (size != TARGET_PAGE_SIZE) {
>          tlb_add_large_page(env, vaddr, size);
>      }
> -    section = phys_page_find(paddr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, paddr >> TARGET_PAGE_BITS);
>  #if defined(DEBUG_TLB)
>      printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
>             " prot=%x idx=%d pd=0x%08lx\n",
> diff --git a/cputlb.h b/cputlb.h
> index 2dc2c96..d537b77 100644
> --- a/cputlb.h
> +++ b/cputlb.h
> @@ -26,7 +26,8 @@ void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
>                               target_ulong vaddr);
>  void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
>                             uintptr_t length);
> -MemoryRegionSection *phys_page_find(target_phys_addr_t index);
> +MemoryRegionSection *phys_page_find(struct AddressSpaceDispatch *d,
> +                                    target_phys_addr_t index);
>  void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
>  void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
>  extern int tlb_flush_count;
> diff --git a/exec.c b/exec.c
> index 7a76efa..42f9ad1 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -187,7 +187,6 @@
>  static void *l1_map[V_L1_SIZE];
>  
>  #if !defined(CONFIG_USER_ONLY)
> -typedef struct PhysPageEntry PhysPageEntry;
>  
>  static MemoryRegionSection *phys_sections;
>  static unsigned phys_sections_nb, phys_sections_nb_alloc;
> @@ -196,22 +195,12 @@
>  static uint16_t phys_section_rom;
>  static uint16_t phys_section_watch;
>  
> -struct PhysPageEntry {
> -    uint16_t is_leaf : 1;
> -     /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
> -    uint16_t ptr : 15;
> -};
> -
>  /* Simple allocator for PhysPageEntry nodes */
>  static PhysPageEntry (*phys_map_nodes)[L2_SIZE];
>  static unsigned phys_map_nodes_nb, phys_map_nodes_nb_alloc;
>  
>  #define PHYS_MAP_NODE_NIL (((uint16_t)~0) >> 1)
>  
> -/* This is a multi-level map on the physical address space.
> -   The bottom level has pointers to MemoryRegionSections.  */
> -static PhysPageEntry phys_map = { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
> -
>  static void io_mem_init(void);
>  static void memory_map_init(void);
>  
> @@ -459,18 +448,19 @@ static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t *index,
>      }
>  }
>  
> -static void phys_page_set(target_phys_addr_t index, target_phys_addr_t nb,
> +static void phys_page_set(AddressSpaceDispatch *d,
> +                          target_phys_addr_t index, target_phys_addr_t nb,
>                            uint16_t leaf)
>  {
>      /* Wildly overreserve - it doesn't matter much. */
>      phys_map_node_reserve(3 * P_L2_LEVELS);
>  
> -    phys_page_set_level(&phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
> +    phys_page_set_level(&d->phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
>  }
>  
> -MemoryRegionSection *phys_page_find(target_phys_addr_t index)
> +MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, target_phys_addr_t index)
>  {
> -    PhysPageEntry lp = phys_map;
> +    PhysPageEntry lp = d->phys_map;
>      PhysPageEntry *p;
>      int i;
>      uint16_t s_index = phys_section_unassigned;
> @@ -1472,7 +1462,7 @@ void tb_invalidate_phys_addr(target_phys_addr_t addr)
>      ram_addr_t ram_addr;
>      MemoryRegionSection *section;
>  
> -    section = phys_page_find(addr >> TARGET_PAGE_BITS);
> +    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
>      if (!(memory_region_is_ram(section->mr)
>            || (section->mr->rom_device && section->mr->readable))) {
>          return;
> @@ -2218,9 +2208,9 @@ static void destroy_l2_mapping(PhysPageEntry *lp, unsigned level)
>      lp->ptr = PHYS_MAP_NODE_NIL;
>  }
>  
> -static void destroy_all_mappings(void)
> +static void destroy_all_mappings(AddressSpaceDispatch *d)
>  {
> -    destroy_l2_mapping(&phys_map, P_L2_LEVELS - 1);
> +    destroy_l2_mapping(&d->phys_map, P_L2_LEVELS - 1);
>      phys_map_nodes_reset();
>  }
>  
> @@ -2240,12 +2230,12 @@ static void phys_sections_clear(void)
>      phys_sections_nb = 0;
>  }
>  
> -static void register_subpage(MemoryRegionSection *section)
> +static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section)
>  {
>      subpage_t *subpage;
>      target_phys_addr_t base = section->offset_within_address_space
>          & TARGET_PAGE_MASK;
> -    MemoryRegionSection *existing = phys_page_find(base >> TARGET_PAGE_BITS);
> +    MemoryRegionSection *existing = phys_page_find(d, base >> TARGET_PAGE_BITS);
>      MemoryRegionSection subsection = {
>          .offset_within_address_space = base,
>          .size = TARGET_PAGE_SIZE,
> @@ -2257,7 +2247,7 @@ static void register_subpage(MemoryRegionSection *section)
>      if (!(existing->mr->subpage)) {
>          subpage = subpage_init(base);
>          subsection.mr = &subpage->iomem;
> -        phys_page_set(base >> TARGET_PAGE_BITS, 1,
> +        phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
>                        phys_section_add(&subsection));
>      } else {
>          subpage = container_of(existing->mr, subpage_t, iomem);
> @@ -2268,7 +2258,7 @@ static void register_subpage(MemoryRegionSection *section)
>  }
>  
>  
> -static void register_multipage(MemoryRegionSection *section)
> +static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *section)
>  {
>      target_phys_addr_t start_addr = section->offset_within_address_space;
>      ram_addr_t size = section->size;
> @@ -2278,13 +2268,13 @@ static void register_multipage(MemoryRegionSection *section)
>      assert(size);
>  
>      addr = start_addr;
> -    phys_page_set(addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS,
> +    phys_page_set(d, addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS,
>                    section_index);
>  }
>  
> -void cpu_register_physical_memory_log(MemoryRegionSection *section,
> -                                      bool readonly)
> +static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
>  {
> +    AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
>      MemoryRegionSection now = *section, remain = *section;
>  
>      if ((now.offset_within_address_space & ~TARGET_PAGE_MASK)
> @@ -2292,7 +2282,7 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
>          now.size = MIN(TARGET_PAGE_ALIGN(now.offset_within_address_space)
>                         - now.offset_within_address_space,
>                         now.size);
> -        register_subpage(&now);
> +        register_subpage(d, &now);
>          remain.size -= now.size;
>          remain.offset_within_address_space += now.size;
>          remain.offset_within_region += now.size;
> @@ -2301,10 +2291,10 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
>          now = remain;
>          if (remain.offset_within_region & ~TARGET_PAGE_MASK) {
>              now.size = TARGET_PAGE_SIZE;
> -            register_subpage(&now);
> +            register_subpage(d, &now);
>          } else {
>              now.size &= TARGET_PAGE_MASK;
> -            register_multipage(&now);
> +            register_multipage(d, &now);
>          }
>          remain.size -= now.size;
>          remain.offset_within_address_space += now.size;
> @@ -2312,7 +2302,7 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
>      }
>      now = remain;
>      if (now.size) {
> -        register_subpage(&now);
> +        register_subpage(d, &now);
>      }
>  }
>  
> @@ -3163,11 +3153,17 @@ static void io_mem_init(void)
>                            "watch", UINT64_MAX);
>  }
>  
> +static void mem_begin(MemoryListener *listener)
> +{
> +    AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
> +
> +    destroy_all_mappings(d);
> +    d->phys_map.ptr = PHYS_MAP_NODE_NIL;
> +}
> +
>  static void core_begin(MemoryListener *listener)
>  {
> -    destroy_all_mappings();
>      phys_sections_clear();
> -    phys_map.ptr = PHYS_MAP_NODE_NIL;
>      phys_section_unassigned = dummy_section(&io_mem_unassigned);
>      phys_section_notdirty = dummy_section(&io_mem_notdirty);
>      phys_section_rom = dummy_section(&io_mem_rom);
> @@ -3186,18 +3182,6 @@ static void tcg_commit(MemoryListener *listener)
>      }
>  }
>  
> -static void core_region_add(MemoryListener *listener,
> -                            MemoryRegionSection *section)
> -{
> -    cpu_register_physical_memory_log(section, section->readonly);
> -}
> -
> -static void core_region_nop(MemoryListener *listener,
> -                            MemoryRegionSection *section)
> -{
> -    cpu_register_physical_memory_log(section, section->readonly);
> -}
> -
>  static void core_log_global_start(MemoryListener *listener)
>  {
>      cpu_physical_memory_set_dirty_tracking(1);
> @@ -3229,11 +3213,9 @@ static void io_region_del(MemoryListener *listener,
>  static MemoryListener core_memory_listener = {
>      MEMORY_LISTENER_DEFAULT_OPS,
>      .begin = core_begin,
> -    .region_add = core_region_add,
> -    .region_nop = core_region_nop,
>      .log_global_start = core_log_global_start,
>      .log_global_stop = core_log_global_stop,
> -    .priority = 0,
> +    .priority = 1,
>  };
>  
>  static MemoryListener io_memory_listener = {
> @@ -3248,6 +3230,22 @@ static void io_region_del(MemoryListener *listener,
>      .commit = tcg_commit,
>  };
>  
> +void address_space_init_dispatch(AddressSpace *as)
> +{
> +    AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);
> +
> +    d->phys_map  = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
> +    d->listener = (MemoryListener) {
> +        MEMORY_LISTENER_DEFAULT_OPS,
> +        .begin = mem_begin,
> +        .region_add = mem_add,
> +        .region_nop = mem_add,
> +        .priority = 0,
> +    };

I see you've become fond of this extension :-)

I'd personally avoid it...  You're typing more than you need to.

BTW, if you make the earlier change I suggested, the
MEMORY_LISTENER_DEFAULT_OPS is no longer necessary.

Regards,

Anthony Liguori

> diff --git a/memory-internal.h b/memory-internal.h
> index 655f71f..a9d914e 100644
> --- a/memory-internal.h
> +++ b/memory-internal.h
> @@ -21,6 +21,26 @@
>  
>  #ifndef CONFIG_USER_ONLY
>  
> +typedef struct PhysPageEntry PhysPageEntry;
> +
> +struct PhysPageEntry {
> +    uint16_t is_leaf : 1;
> +     /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
> +    uint16_t ptr : 15;
> +};
> +
> +typedef struct AddressSpaceDispatch AddressSpaceDispatch;
> +
> +struct AddressSpaceDispatch {
> +    /* This is a multi-level map on the physical address space.
> +     * The bottom level has pointers to MemoryRegionSections.
> +     */
> +    PhysPageEntry phys_map;
> +    MemoryListener listener;
> +};
> +
> +void address_space_init_dispatch(AddressSpace *as);
> +
>  ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>                                     MemoryRegion *mr);
>  ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
> @@ -29,8 +49,6 @@ void qemu_ram_free_from_ptr(ram_addr_t addr);
>  
>  struct MemoryRegion;
>  struct MemoryRegionSection;
> -void cpu_register_physical_memory_log(struct MemoryRegionSection *section,
> -                                      bool readonly);
>  
>  void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
>  void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
> diff --git a/memory.c b/memory.c
> index f829d84..28a79ae 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1550,6 +1550,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
>      QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
>      as->name = NULL;
>      memory_region_transaction_commit();
> +    address_space_init_dispatch(as);
>  }
>  
>  uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
> diff --git a/memory.h b/memory.h
> index 6115f48..84f7439 100644
> --- a/memory.h
> +++ b/memory.h
> @@ -169,6 +169,7 @@ struct AddressSpace {
>      struct FlatView *current_map;
>      int ioeventfd_nb;
>      struct MemoryRegionIoeventfd *ioeventfds;
> +    struct AddressSpaceDispatch *dispatch;
>      QTAILQ_ENTRY(AddressSpace) address_spaces_link;
>  };
>  
> @@ -830,6 +831,67 @@ void mtree_info(fprintf_function mon_printf, void *f);
>   */
>  void address_space_init(AddressSpace *as, MemoryRegion *root);
>  
> +/**
> + * address_space_rw: read from or write to an address space.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @buf: buffer with the data transferred
> + * @is_write: indicates the transfer direction
> + */
> +void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf,
> +                      int len, bool is_write);
> +
> +/**
> + * address_space_write: write to address space.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @buf: buffer with the data transferred
> + */
> +void address_space_write(AddressSpace *as, target_phys_addr_t addr,
> +                         const uint8_t *buf, int len);
> +
> +/**
> + * address_space_read: read from an address space.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @buf: buffer with the data transferred
> + */
> +void address_space_read(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, int len);
> +
> +/* address_space_map: map a physical memory region into a host virtual address
> + *
> + * May map a subset of the requested range, given by and returned in @plen.
> + * May return %NULL if resources needed to perform the mapping are exhausted.
> + * Use only for reads OR writes - not for read-modify-write operations.
> + * Use cpu_register_map_client() to know when retrying the map operation is
> + * likely to succeed.
> + *
> + * @as: #AddressSpace to be accessed
> + * @addr: address within that address space
> + * @plen: pointer to length of buffer; updated on return
> + * @is_write: indicates the transfer direction
> + */
> +void *address_space_map(AddressSpace *as, target_phys_addr_t addr,
> +                        target_phys_addr_t *plen, bool is_write);
> +
> +/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
> + *
> + * Will also mark the memory as dirty if @is_write == %true.  @access_len gives
> + * the amount of memory that was actually read or written by the caller.
> + *
> + * @as: #AddressSpace used
> + * @addr: address within that address space
> + * @len: buffer length as returned by address_space_map()
> + * @access_len: amount of data actually transferred
> + * @is_write: indicates the transfer direction
> + */
> +void address_space_unmap(AddressSpace *as, void *buffer, target_phys_addr_t len,
> +                         int is_write, target_phys_addr_t access_len);
> +
> +
>  #endif
>  
>  #endif
> -- 
> 1.7.12

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

* Re: [Qemu-devel] [RFC v1 20/22] dma: make dma access its own address space
  2012-10-03 16:04 ` [Qemu-devel] [RFC v1 20/22] dma: make dma access its own address space Avi Kivity
@ 2012-10-04 14:15   ` Anthony Liguori
  0 siblings, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:15 UTC (permalink / raw)
  To: Avi Kivity, qemu-devel, liu ping fan, Michael S. Tsirkin,
	Paolo Bonzini, Blue Swirl

Avi Kivity <avi@redhat.com> writes:

> Instead of accessing the cpu address space, use an address space
> configured by the caller.
>
> Eventually all dma functionality will be folded into AddressSpace,
> but we have to start from something.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

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

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

* Re: [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API
  2012-10-04  8:13 ` Paolo Bonzini
@ 2012-10-04 14:16   ` Anthony Liguori
  2012-10-04 14:36     ` Avi Kivity
  0 siblings, 1 reply; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 14:16 UTC (permalink / raw)
  To: Paolo Bonzini, Avi Kivity
  Cc: Blue Swirl, Michael S. Tsirkin, qemu-devel, liu ping fan

Paolo Bonzini <pbonzini@redhat.com> writes:

> Il 03/10/2012 18:03, Avi Kivity ha scritto:
>> 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.
>
> Very nice, IMHO patches 1-18 should get in soon.  They are a useful
> cleanup on their own.

Yup, other than a few minor cosmetics, the series is a very nice
cleanup.

I think this probably gets us fairly close to being able to write unit
tests for the memory layer too which is really nice.

Regards,

Anthony Liguori

>
> Paolo
>
>> Avi Kivity (22):
>>   memory: rename 'exec-obsolete.h'
>>   vhost: use MemoryListener filtering to only monitor RAM address space
>>   kvm: use separate MemoryListeners for memory and I/O
>>   xen_pt: use separate MemoryListeners for memory and I/O
>>   memory: prepare AddressSpace for exporting
>>   memory: export AddressSpace
>>   memory: maintain a list of address spaces
>>   memory: provide defaults for MemoryListener operations
>>   memory: use new MEMORY_LISTENER_DEFAULT_OPS
>>   vfio: use new MEMORY_LISTENER_DEFAULT_OPS
>>   xen_pt: use new MEMORY_LISTENER_DEFAULT_OPS
>>   kvm: use new MEMORY_LISTENER_DEFAULT_OPS
>>   xen: use new MEMORY_LISTENER_DEFAULT_OPS
>>   memory: manage coalesced mmio via a MemoryListener
>>   memory: move address_space_memory and address_space_io out of memory
>>     core
>>   memory: move tcg flush into a tcg memory listener
>>   memory: use AddressSpace for MemoryListener filtering
>>   s390: avoid reaching into memory core internals
>>   memory: per-AddressSpace dispatch
>>   dma: make dma access its own address space
>>   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                               | 312 ++++++++++++++---------------------
>>  hw/Makefile.objs                     |   5 +-
>>  hw/pci.c                             |  19 ++-
>>  hw/pci.h                             |   2 +
>>  hw/spapr_iommu.c                     |   3 +-
>>  hw/vfio_pci.c                        |  33 +---
>>  hw/vhost.c                           |   5 +-
>>  hw/xen_pt.c                          |  49 +++---
>>  hw/xen_pt.h                          |   1 +
>>  kvm-all.c                            | 107 +++++-------
>>  kvm-stub.c                           |  10 --
>>  kvm.h                                |   2 -
>>  exec-obsolete.h => memory-internal.h |  30 +++-
>>  memory.c                             | 158 +++++++++++-------
>>  memory.h                             | 122 +++++++++++++-
>>  target-s390x/misc_helper.c           |   2 +-
>>  xen-all.c                            |  45 +----
>>  22 files changed, 487 insertions(+), 476 deletions(-)
>>  rename exec-obsolete.h => memory-internal.h (87%)
>> 

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

* Re: [Qemu-devel] [RFC v1 08/22] memory: provide defaults for MemoryListener operations
  2012-10-04 14:05   ` Anthony Liguori
@ 2012-10-04 14:29     ` Avi Kivity
  2012-10-09 15:14       ` Anthony Liguori
  0 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 14:29 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

On 10/04/2012 04:05 PM, Anthony Liguori wrote:
> Avi Kivity <avi@redhat.com> writes:
> 
>> Many listeners don't need to respond to all MemoryListener callbacks;
>> provide suitable defaults instead.
>>

>> +#define MEMORY_LISTENER_DEFAULT_OPS                         \
>> +    .begin = memory_listener_default_global,                \
>> +    .commit = memory_listener_default_global,               \
>> +    .region_add = memory_listener_default_section,          \
>> +    .region_del = memory_listener_default_section,          \
>> +    .region_nop = memory_listener_default_section,          \
>> +    .log_start = memory_listener_default_section,           \
>> +    .log_stop = memory_listener_default_section,            \
>> +    .log_sync = memory_listener_default_section,            \
>> +    .log_global_start = memory_listener_default_global,     \
>> +    .log_global_stop = memory_listener_default_global,      \
>> +    .eventfd_add = memory_listener_default_eventfd,         \
>> +    .eventfd_del = memory_listener_default_eventfd          \
>> +
>> +void memory_listener_default_global(MemoryListener *listener);
>> +void memory_listener_default_section(MemoryListener *listener,
>> +                                     MemoryRegionSection *section);
>> +void memory_listener_default_eventfd(MemoryListener *listener,
>> +                                     MemoryRegionSection *section,
>> +                                     bool match_data, uint64_t data, EventNotifier *e);
>> +
>>  /**
>>   * memory_region_init: Initialize a memory region
>>   *
> 
> I think it'd be nicer to check for NULL when invoking the functions in
> the memory core.
> 
> Then you avoid the exported stub functions entirely.

Yes, that's the common style, but I happen not to like the extra check,
both from a performance point of view (doesn't apply here of course) and
from a readability point of view.

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

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

* Re: [Qemu-devel] [RFC v1 14/22] memory: manage coalesced mmio via a MemoryListener
  2012-10-04 14:08   ` Anthony Liguori
@ 2012-10-04 14:33     ` Avi Kivity
  0 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 14:33 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

On 10/04/2012 04:08 PM, Anthony Liguori wrote:
> Avi Kivity <avi@redhat.com> writes:
> 
>> 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.
>>
>> -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);
> 
> g_assert on error instead of ignoring it.

I'll do that in a separate patch, since the existing behaviour is to
ignore the error.  If errors really do happen, I don't want a
refactoring patch to trigger them.

>>  
>> diff --git a/memory.c b/memory.c
>> index efefcb8..eb75349 100644
>> --- a/memory.c
>> +++ b/memory.c
>> @@ -1130,11 +1130,19 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
>>      FlatRange *fr;
>>      CoalescedMemoryRange *cmr;
>>      AddrRange tmp;
>> +    MemoryRegionSection section;
>>  
>>      FOR_EACH_FLAT_RANGE(fr, as->current_map) {
>>          if (fr->mr == mr) {
>> -            qemu_unregister_coalesced_mmio(int128_get64(fr->addr.start),
>> -                                           int128_get64(fr->addr.size));
>> +            section = (MemoryRegionSection) {
>> +                .address_space = as->root,
>> +                .offset_within_address_space = int128_get64(fr->addr.start),
>> +                .size = int128_get64(fr->addr.size),
>> +            };
> 
> I think this is a bit too clever.  You can move the definition of
> section into this block with a zero initializer, and then just set the
> fields directly.  You'll end up losing 2 lines of code in the process
> too.

I happen to like it (I dislike repeating the variable name each line)
but have no problem changing it.


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

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

* Re: [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API
  2012-10-04 14:16   ` Anthony Liguori
@ 2012-10-04 14:36     ` Avi Kivity
  0 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 14:36 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

On 10/04/2012 04:16 PM, Anthony Liguori wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
> 
>> Il 03/10/2012 18:03, Avi Kivity ha scritto:
>>> 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.
>>
>> Very nice, IMHO patches 1-18 should get in soon.  They are a useful
>> cleanup on their own.
> 
> Yup, other than a few minor cosmetics, the series is a very nice
> cleanup.
> 
> I think this probably gets us fairly close to being able to write unit
> tests for the memory layer too which is really nice.

It still hardcodes the call to address_space_init_dispatch().  But I
guess we don't have to be purists and we can have the test framework
supply an alternate version of this function.

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

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 14:13   ` Anthony Liguori
@ 2012-10-04 14:43     ` Avi Kivity
  2012-10-09 15:17       ` Anthony Liguori
  0 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 14:43 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

On 10/04/2012 04:13 PM, Anthony Liguori 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) {
>> +        MEMORY_LISTENER_DEFAULT_OPS,
>> +        .begin = mem_begin,
>> +        .region_add = mem_add,
>> +        .region_nop = mem_add,
>> +        .priority = 0,
>> +    };
> 
> I see you've become fond of this extension :-)

It's not an extension.

> I'd personally avoid it...  You're typing more than you need to.

Don't see why, it seems to me to be a direct way of specifying what you
want.  You can read it literally as "d->phys_map is assigned a
PhysPageEntry structure with ptr = this and is_leaf = that.

The alternatives are:

   memset(&d->phys_map, 0, sizeof(d->phys_map);
   d->phys_map.ptr = PHYS_MAP_NODE_NIL;
   d->phys_map.is_leaf = 0;

or

   PhysPageEntry tmp = { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };

   d->phys_map = tmp;

I find both of these less appealing than the original.

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

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

* Re: [Qemu-devel] [RFC v1 10/22] vfio: use new MEMORY_LISTENER_DEFAULT_OPS
  2012-10-03 16:03 ` [Qemu-devel] [RFC v1 10/22] vfio: " Avi Kivity
@ 2012-10-04 15:45   ` Alex Williamson
  0 siblings, 0 replies; 70+ messages in thread
From: Alex Williamson @ 2012-10-04 15:45 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Michael S. Tsirkin, qemu-devel, liu ping fan, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On Wed, 2012-10-03 at 18:03 +0200, Avi Kivity wrote:
> Removes quite a bit of useless code.
> 
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  hw/vfio_pci.c | 30 +-----------------------------
>  1 file changed, 1 insertion(+), 29 deletions(-)
> 
> diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
> index a1eeced..8e49535 100644
> --- a/hw/vfio_pci.c
> +++ b/hw/vfio_pci.c
> @@ -803,25 +803,6 @@ static int vfio_dma_unmap(VFIOContainer *container,
>      return 0;
>  }
>  
> -static void vfio_listener_dummy1(MemoryListener *listener)
> -{
> -    /* We don't do batching (begin/commit) or care about logging */
> -}
> -
> -static void vfio_listener_dummy2(MemoryListener *listener,
> -                                 MemoryRegionSection *section)
> -{
> -    /* We don't do logging or care about nops */
> -}
> -
> -static void vfio_listener_dummy3(MemoryListener *listener,
> -                                 MemoryRegionSection *section,
> -                                 bool match_data, uint64_t data,
> -                                 EventNotifier *e)
> -{
> -    /* We don't care about eventfds */
> -}
> -
>  static bool vfio_listener_skipped_section(MemoryRegionSection *section)
>  {
>      return !memory_region_is_ram(section->mr);
> @@ -913,18 +894,9 @@ static void vfio_listener_region_del(MemoryListener *listener,
>  }
>  
>  static MemoryListener vfio_memory_listener = {
> -    .begin = vfio_listener_dummy1,
> -    .commit = vfio_listener_dummy1,
> +    MEMORY_LISTENER_DEFAULT_OPS,
>      .region_add = vfio_listener_region_add,
>      .region_del = vfio_listener_region_del,
> -    .region_nop = vfio_listener_dummy2,
> -    .log_start = vfio_listener_dummy2,
> -    .log_stop = vfio_listener_dummy2,
> -    .log_sync = vfio_listener_dummy2,
> -    .log_global_start = vfio_listener_dummy1,
> -    .log_global_stop = vfio_listener_dummy1,
> -    .eventfd_add = vfio_listener_dummy3,
> -    .eventfd_del = vfio_listener_dummy3,
>  };
>  
>  static void vfio_listener_release(VFIOContainer *container)

I'm happy to see this cleanup.  Thanks

Acked-by: Alex Williamson <alex.williamson@redhat.com>

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

* Re: [Qemu-devel] [RFC v1 03/22] kvm: use separate MemoryListeners for memory and I/O
  2012-10-04  6:33     ` Avi Kivity
@ 2012-10-04 16:44       ` Blue Swirl
  2012-10-04 16:58         ` Avi Kivity
  0 siblings, 1 reply; 70+ messages in thread
From: Blue Swirl @ 2012-10-04 16:44 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On Thu, Oct 4, 2012 at 6:33 AM, Avi Kivity <avi@redhat.com> wrote:
> On 10/03/2012 10:16 PM, Blue Swirl wrote:
>> > +static MemoryListener kvm_io_listener = {
>>
>> const
>>
>
> There is a list link field in there.  It's a mixed data/ops structure
> (perhaps we should make it a traditional ->ops-> pointer).

I grepped for MemoryListener and in hw/xen_pt.c 'const' already
exists, so it looked OK but the code actually copies the structure to
writable memory.

>
> --
> I have a truly marvellous patch that fixes the bug which this
> signature is too narrow to contain.
>

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

* Re: [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering
  2012-10-04 10:17     ` Avi Kivity
@ 2012-10-04 16:57       ` Blue Swirl
  0 siblings, 0 replies; 70+ messages in thread
From: Blue Swirl @ 2012-10-04 16:57 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On Thu, Oct 4, 2012 at 10:17 AM, Avi Kivity <avi@redhat.com> wrote:
> On 10/03/2012 10:16 PM, Blue Swirl wrote:
>>> @@ -141,7 +141,7 @@ static bool memory_listener_match(MemoryListener *listener,
>>>  #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
>>>      MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) {       \
>>>          .mr = (fr)->mr,                                                 \
>>> -        .address_space = (as)->root,                                    \
>>> +        .address_space = (as),                                          \
>>
>> Maybe remove parenthesis.
>
> I prefer to keep it for consistency and defensiveness, unless you insist.

I don't, though for example dir is used a few lines earlier without parenthesis.

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

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

* Re: [Qemu-devel] [RFC v1 03/22] kvm: use separate MemoryListeners for memory and I/O
  2012-10-04 16:44       ` Blue Swirl
@ 2012-10-04 16:58         ` Avi Kivity
  0 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 16:58 UTC (permalink / raw)
  To: Blue Swirl
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On 10/04/2012 06:44 PM, Blue Swirl wrote:
> On Thu, Oct 4, 2012 at 6:33 AM, Avi Kivity <avi@redhat.com> wrote:
>> On 10/03/2012 10:16 PM, Blue Swirl wrote:
>>> > +static MemoryListener kvm_io_listener = {
>>>
>>> const
>>>
>>
>> There is a list link field in there.  It's a mixed data/ops structure
>> (perhaps we should make it a traditional ->ops-> pointer).
> 
> I grepped for MemoryListener and in hw/xen_pt.c 'const' already
> exists, so it looked OK but the code actually copies the structure to
> writable memory.

Yes.  We should probably switch to the standard object->ops->callback
pattern.  I'll write a patch after this series is merged.


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

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04  6:38     ` Avi Kivity
  2012-10-04  8:47       ` Peter Maydell
@ 2012-10-04 17:13       ` Blue Swirl
  2012-10-04 17:19         ` Avi Kivity
  1 sibling, 1 reply; 70+ messages in thread
From: Blue Swirl @ 2012-10-04 17:13 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On Thu, Oct 4, 2012 at 6:38 AM, Avi Kivity <avi@redhat.com> wrote:
> On 10/03/2012 10:24 PM, Blue Swirl wrote:
>> >
>> >  #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)
>>
>> I'd make address_space_* use uint64_t instead of target_phys_addr_t
>> for the address. It may actually be buggy for 32 bit
>> target_phys_addr_t  and 64 bit DMA addresses, if such architectures
>> exist. Maybe memory.c could be made target independent one day.
>
> We can make target_phys_addr_t 64 bit unconditionally.  The fraction of
> deployments where both host and guest are 32 bits is dropping, and I
> doubt the performance drop is noticable.

My line of thought was that memory.c would not be tied to physical
addresses, but it would be more general. Then exec.c would specialize
the API to use target_phys_addr_t. Similarly PCI would specialize it
to pcibus_t, PIO to pio_addr_t and DMA to dma_addr_t.

>
> We were also planning to rename target_phys_addt_t to hw_addr.
>
> But both of those are for another patch.  For now, AddressSpace follows
> MemoryRegion, it's just a small abstraction on top.
>
>
> --
> I have a truly marvellous patch that fixes the bug which this
> signature is too narrow to contain.
>

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 17:13       ` Blue Swirl
@ 2012-10-04 17:19         ` Avi Kivity
  2012-10-04 17:42           ` Blue Swirl
  0 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-04 17:19 UTC (permalink / raw)
  To: Blue Swirl
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On 10/04/2012 07:13 PM, Blue Swirl wrote:
> On Thu, Oct 4, 2012 at 6:38 AM, Avi Kivity <avi@redhat.com> wrote:
>> On 10/03/2012 10:24 PM, Blue Swirl wrote:
>>> >
>>> >  #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)
>>>
>>> I'd make address_space_* use uint64_t instead of target_phys_addr_t
>>> for the address. It may actually be buggy for 32 bit
>>> target_phys_addr_t  and 64 bit DMA addresses, if such architectures
>>> exist. Maybe memory.c could be made target independent one day.
>>
>> We can make target_phys_addr_t 64 bit unconditionally.  The fraction of
>> deployments where both host and guest are 32 bits is dropping, and I
>> doubt the performance drop is noticable.
> 
> My line of thought was that memory.c would not be tied to physical
> addresses, but it would be more general. Then exec.c would specialize
> the API to use target_phys_addr_t. Similarly PCI would specialize it
> to pcibus_t, PIO to pio_addr_t and DMA to dma_addr_t.

The problem is that all any transition across the boundaries would then
involve casts (explicit or implicit) with the constant worry of whether
we're truncating or not.  Note we have transitions in both directions,
with the higher layer APIs calling memory APIs, and the memory API
calling them back via MemoryRegionOps or a new MemoryRegionIOMMUOps.

What does this flexibility buy us, compared to a single hw_addr fixed at
64 bits?


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

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 17:19         ` Avi Kivity
@ 2012-10-04 17:42           ` Blue Swirl
  2012-10-04 19:05             ` Anthony Liguori
  0 siblings, 1 reply; 70+ messages in thread
From: Blue Swirl @ 2012-10-04 17:42 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, Anthony Liguori,
	liu ping fan

On Thu, Oct 4, 2012 at 5:19 PM, Avi Kivity <avi@redhat.com> wrote:
> On 10/04/2012 07:13 PM, Blue Swirl wrote:
>> On Thu, Oct 4, 2012 at 6:38 AM, Avi Kivity <avi@redhat.com> wrote:
>>> On 10/03/2012 10:24 PM, Blue Swirl wrote:
>>>> >
>>>> >  #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)
>>>>
>>>> I'd make address_space_* use uint64_t instead of target_phys_addr_t
>>>> for the address. It may actually be buggy for 32 bit
>>>> target_phys_addr_t  and 64 bit DMA addresses, if such architectures
>>>> exist. Maybe memory.c could be made target independent one day.
>>>
>>> We can make target_phys_addr_t 64 bit unconditionally.  The fraction of
>>> deployments where both host and guest are 32 bits is dropping, and I
>>> doubt the performance drop is noticable.
>>
>> My line of thought was that memory.c would not be tied to physical
>> addresses, but it would be more general. Then exec.c would specialize
>> the API to use target_phys_addr_t. Similarly PCI would specialize it
>> to pcibus_t, PIO to pio_addr_t and DMA to dma_addr_t.
>
> The problem is that all any transition across the boundaries would then
> involve casts (explicit or implicit) with the constant worry of whether
> we're truncating or not.  Note we have transitions in both directions,
> with the higher layer APIs calling memory APIs, and the memory API
> calling them back via MemoryRegionOps or a new MemoryRegionIOMMUOps.
>
> What does this flexibility buy us, compared to a single hw_addr fixed at
> 64 bits?

They can all be 64 bits, I'm just considering types. Getting rid of
target_phys_addr_t, pcibus_t, pio_addr_t and dma_addr_t (are there
more?) may be also worthwhile.

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

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 17:42           ` Blue Swirl
@ 2012-10-04 19:05             ` Anthony Liguori
  2012-10-04 19:15               ` Blue Swirl
  2012-10-04 19:16               ` Peter Maydell
  0 siblings, 2 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-04 19:05 UTC (permalink / raw)
  To: Blue Swirl, Avi Kivity
  Cc: Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

Blue Swirl <blauwirbel@gmail.com> writes:

> On Thu, Oct 4, 2012 at 5:19 PM, Avi Kivity <avi@redhat.com> wrote:
>> On 10/04/2012 07:13 PM, Blue Swirl wrote:
>>> On Thu, Oct 4, 2012 at 6:38 AM, Avi Kivity <avi@redhat.com> wrote:
>>>> On 10/03/2012 10:24 PM, Blue Swirl wrote:
>>>>> >
>>>>> >  #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)
>>>>>
>>>>> I'd make address_space_* use uint64_t instead of target_phys_addr_t
>>>>> for the address. It may actually be buggy for 32 bit
>>>>> target_phys_addr_t  and 64 bit DMA addresses, if such architectures
>>>>> exist. Maybe memory.c could be made target independent one day.
>>>>
>>>> We can make target_phys_addr_t 64 bit unconditionally.  The fraction of
>>>> deployments where both host and guest are 32 bits is dropping, and I
>>>> doubt the performance drop is noticable.
>>>
>>> My line of thought was that memory.c would not be tied to physical
>>> addresses, but it would be more general. Then exec.c would specialize
>>> the API to use target_phys_addr_t. Similarly PCI would specialize it
>>> to pcibus_t, PIO to pio_addr_t and DMA to dma_addr_t.
>>
>> The problem is that all any transition across the boundaries would then
>> involve casts (explicit or implicit) with the constant worry of whether
>> we're truncating or not.  Note we have transitions in both directions,
>> with the higher layer APIs calling memory APIs, and the memory API
>> calling them back via MemoryRegionOps or a new MemoryRegionIOMMUOps.
>>
>> What does this flexibility buy us, compared to a single hw_addr fixed at
>> 64 bits?
>
> They can all be 64 bits, I'm just considering types. Getting rid of
> target_phys_addr_t, pcibus_t, pio_addr_t and dma_addr_t (are there
> more?) may be also worthwhile.

Where this breaks down is devices that are DMA capable but may exist on
multiple busses.

So you either end up with a device-specific type and a layer of casting
or weird acrobatics.

It makes more sense IMHO to just treat bus addresses as a fixed with.

target_phys_addr_t is a bad name.  I'd be in favor of either just using
uint64_t directly or having a generic dma_addr_t.

Regards,

Anthony Liguori

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

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 19:05             ` Anthony Liguori
@ 2012-10-04 19:15               ` Blue Swirl
  2012-10-04 19:16               ` Peter Maydell
  1 sibling, 0 replies; 70+ messages in thread
From: Blue Swirl @ 2012-10-04 19:15 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Paolo Bonzini, liu ping fan, Michael S. Tsirkin, Avi Kivity, qemu-devel

On Thu, Oct 4, 2012 at 7:05 PM, Anthony Liguori <anthony@codemonkey.ws> wrote:
> Blue Swirl <blauwirbel@gmail.com> writes:
>
>> On Thu, Oct 4, 2012 at 5:19 PM, Avi Kivity <avi@redhat.com> wrote:
>>> On 10/04/2012 07:13 PM, Blue Swirl wrote:
>>>> On Thu, Oct 4, 2012 at 6:38 AM, Avi Kivity <avi@redhat.com> wrote:
>>>>> On 10/03/2012 10:24 PM, Blue Swirl wrote:
>>>>>> >
>>>>>> >  #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)
>>>>>>
>>>>>> I'd make address_space_* use uint64_t instead of target_phys_addr_t
>>>>>> for the address. It may actually be buggy for 32 bit
>>>>>> target_phys_addr_t  and 64 bit DMA addresses, if such architectures
>>>>>> exist. Maybe memory.c could be made target independent one day.
>>>>>
>>>>> We can make target_phys_addr_t 64 bit unconditionally.  The fraction of
>>>>> deployments where both host and guest are 32 bits is dropping, and I
>>>>> doubt the performance drop is noticable.
>>>>
>>>> My line of thought was that memory.c would not be tied to physical
>>>> addresses, but it would be more general. Then exec.c would specialize
>>>> the API to use target_phys_addr_t. Similarly PCI would specialize it
>>>> to pcibus_t, PIO to pio_addr_t and DMA to dma_addr_t.
>>>
>>> The problem is that all any transition across the boundaries would then
>>> involve casts (explicit or implicit) with the constant worry of whether
>>> we're truncating or not.  Note we have transitions in both directions,
>>> with the higher layer APIs calling memory APIs, and the memory API
>>> calling them back via MemoryRegionOps or a new MemoryRegionIOMMUOps.
>>>
>>> What does this flexibility buy us, compared to a single hw_addr fixed at
>>> 64 bits?
>>
>> They can all be 64 bits, I'm just considering types. Getting rid of
>> target_phys_addr_t, pcibus_t, pio_addr_t and dma_addr_t (are there
>> more?) may be also worthwhile.
>
> Where this breaks down is devices that are DMA capable but may exist on
> multiple busses.
>
> So you either end up with a device-specific type and a layer of casting
> or weird acrobatics.

OK, less types is better.

>
> It makes more sense IMHO to just treat bus addresses as a fixed with.
>
> target_phys_addr_t is a bad name.  I'd be in favor of either just using
> uint64_t directly or having a generic dma_addr_t.

Simplest would be uint64_t for all, one unified address type may have
type safety benefits.

>
> Regards,
>
> Anthony Liguori
>
>>
>>>
>>>
>>> --
>>> error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 19:05             ` Anthony Liguori
  2012-10-04 19:15               ` Blue Swirl
@ 2012-10-04 19:16               ` Peter Maydell
  2012-10-07 10:34                 ` Avi Kivity
  1 sibling, 1 reply; 70+ messages in thread
From: Peter Maydell @ 2012-10-04 19:16 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Michael S. Tsirkin, qemu-devel, liu ping fan, Blue Swirl,
	Avi Kivity, Paolo Bonzini

On 4 October 2012 20:05, Anthony Liguori <anthony@codemonkey.ws> wrote:
> Blue Swirl <blauwirbel@gmail.com> writes:
>> They can all be 64 bits, I'm just considering types. Getting rid of
>> target_phys_addr_t, pcibus_t, pio_addr_t and dma_addr_t (are there
>> more?) may be also worthwhile.
>
> Where this breaks down is devices that are DMA capable but may exist on
> multiple busses.
>
> So you either end up with a device-specific type and a layer of casting
> or weird acrobatics.
>
> It makes more sense IMHO to just treat bus addresses as a fixed with.
>
> target_phys_addr_t is a bad name.  I'd be in favor of either just using
> uint64_t directly or having a generic dma_addr_t.

I agree that we only need one type; I think it's helpful to
have a type name rather than direct use of uint64_t. dma_addr_t
doesn't seem right because most of the usage of it isn't going to
be in DMA related contexts. addr_t ?

-- PMM

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 19:16               ` Peter Maydell
@ 2012-10-07 10:34                 ` Avi Kivity
  0 siblings, 0 replies; 70+ messages in thread
From: Avi Kivity @ 2012-10-07 10:34 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Michael S. Tsirkin, liu ping fan, qemu-devel, Blue Swirl,
	Anthony Liguori, Paolo Bonzini

On 10/04/2012 09:16 PM, Peter Maydell wrote:
> On 4 October 2012 20:05, Anthony Liguori <anthony@codemonkey.ws> wrote:
>> Blue Swirl <blauwirbel@gmail.com> writes:
>>> They can all be 64 bits, I'm just considering types. Getting rid of
>>> target_phys_addr_t, pcibus_t, pio_addr_t and dma_addr_t (are there
>>> more?) may be also worthwhile.
>>
>> Where this breaks down is devices that are DMA capable but may exist on
>> multiple busses.
>>
>> So you either end up with a device-specific type and a layer of casting
>> or weird acrobatics.
>>
>> It makes more sense IMHO to just treat bus addresses as a fixed with.
>>
>> target_phys_addr_t is a bad name.  I'd be in favor of either just using
>> uint64_t directly or having a generic dma_addr_t.
> 
> I agree that we only need one type; I think it's helpful to
> have a type name rather than direct use of uint64_t. dma_addr_t
> doesn't seem right because most of the usage of it isn't going to
> be in DMA related contexts. addr_t ?

*_t is reserved.

Suggestions:

 phys
 Phys
 hwaddr
 hw_addr

there are some variables named 'phys' scattered in the source, so my
current favorite is hwaddr.  Short and to the point.

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

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

* Re: [Qemu-devel] [RFC v1 08/22] memory: provide defaults for MemoryListener operations
  2012-10-04 14:29     ` Avi Kivity
@ 2012-10-09 15:14       ` Anthony Liguori
  2012-10-09 15:28         ` Avi Kivity
  0 siblings, 1 reply; 70+ messages in thread
From: Anthony Liguori @ 2012-10-09 15:14 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

Avi Kivity <avi@redhat.com> writes:

> On 10/04/2012 04:05 PM, Anthony Liguori wrote:
>> Avi Kivity <avi@redhat.com> writes:
>> 
>>> Many listeners don't need to respond to all MemoryListener callbacks;
>>> provide suitable defaults instead.
>>>
>
>>> +#define MEMORY_LISTENER_DEFAULT_OPS                         \
>>> +    .begin = memory_listener_default_global,                \
>>> +    .commit = memory_listener_default_global,               \
>>> +    .region_add = memory_listener_default_section,          \
>>> +    .region_del = memory_listener_default_section,          \
>>> +    .region_nop = memory_listener_default_section,          \
>>> +    .log_start = memory_listener_default_section,           \
>>> +    .log_stop = memory_listener_default_section,            \
>>> +    .log_sync = memory_listener_default_section,            \
>>> +    .log_global_start = memory_listener_default_global,     \
>>> +    .log_global_stop = memory_listener_default_global,      \
>>> +    .eventfd_add = memory_listener_default_eventfd,         \
>>> +    .eventfd_del = memory_listener_default_eventfd          \
>>> +
>>> +void memory_listener_default_global(MemoryListener *listener);
>>> +void memory_listener_default_section(MemoryListener *listener,
>>> +                                     MemoryRegionSection *section);
>>> +void memory_listener_default_eventfd(MemoryListener *listener,
>>> +                                     MemoryRegionSection *section,
>>> +                                     bool match_data, uint64_t data, EventNotifier *e);
>>> +
>>>  /**
>>>   * memory_region_init: Initialize a memory region
>>>   *
>> 
>> I think it'd be nicer to check for NULL when invoking the functions in
>> the memory core.
>> 
>> Then you avoid the exported stub functions entirely.
>
> Yes, that's the common style, but I happen not to like the extra check,
> both from a performance point of view (doesn't apply here of course) and
> from a readability point of view.

The trouble with your approach is that it introduced a subtle behavior
based on ordering.   IOW:

MemoryListenerOps foo = {
    MEMORY_LISTENER_DEFAULT_OPS,
    .log_sync = ...,
};

vs.

MemoryListenerOps foo = {
    .log_sync = ...,
    MEMORY_LISTENER_DEFAULT_OPS,
};

Both compile fine but have potentially difficult to debug differences.
Relying on zero-initialization eliminates the possibility of this problem.

Regards,

Anthony Liguori

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

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

* Re: [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch
  2012-10-04 14:43     ` Avi Kivity
@ 2012-10-09 15:17       ` Anthony Liguori
  0 siblings, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-09 15:17 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

Avi Kivity <avi@redhat.com> writes:

> On 10/04/2012 04:13 PM, Anthony Liguori 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) {
>>> +        MEMORY_LISTENER_DEFAULT_OPS,
>>> +        .begin = mem_begin,
>>> +        .region_add = mem_add,
>>> +        .region_nop = mem_add,
>>> +        .priority = 0,
>>> +    };
>> 
>> I see you've become fond of this extension :-)
>
> It's not an extension.
>
>> I'd personally avoid it...  You're typing more than you need to.
>
> Don't see why, it seems to me to be a direct way of specifying what you
> want.  You can read it literally as "d->phys_map is assigned a
> PhysPageEntry structure with ptr = this and is_leaf = that.
>
> The alternatives are:
>
>    memset(&d->phys_map, 0, sizeof(d->phys_map);
>    d->phys_map.ptr = PHYS_MAP_NODE_NIL;
>    d->phys_map.is_leaf = 0;
>
> or
>
>    PhysPageEntry tmp = { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
>
>    d->phys_map = tmp;
>
> I find both of these less appealing than the original.

I don't really care about the use of struct literals...

You are typing more than you need to.  The bit that I think really
matters is using zero-initialization as the default vs. using a macro.

Regards,

Anthony Liguori

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

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

* Re: [Qemu-devel] [RFC v1 08/22] memory: provide defaults for MemoryListener operations
  2012-10-09 15:14       ` Anthony Liguori
@ 2012-10-09 15:28         ` Avi Kivity
  2012-10-09 18:34           ` Anthony Liguori
  0 siblings, 1 reply; 70+ messages in thread
From: Avi Kivity @ 2012-10-09 15:28 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

On 10/09/2012 05:14 PM, Anthony Liguori wrote:
>>> 
>>> I think it'd be nicer to check for NULL when invoking the functions in
>>> the memory core.
>>> 
>>> Then you avoid the exported stub functions entirely.
>>
>> Yes, that's the common style, but I happen not to like the extra check,
>> both from a performance point of view (doesn't apply here of course) and
>> from a readability point of view.
> 
> The trouble with your approach is that it introduced a subtle behavior
> based on ordering.   IOW:
> 
> MemoryListenerOps foo = {
>     MEMORY_LISTENER_DEFAULT_OPS,
>     .log_sync = ...,
> };
> 
> vs.
> 
> MemoryListenerOps foo = {
>     .log_sync = ...,
>     MEMORY_LISTENER_DEFAULT_OPS,
> };
> 
> Both compile fine but have potentially difficult to debug differences.
> Relying on zero-initialization eliminates the possibility of this problem.
> 

I don't think this is likely (esp. as the bad behaviour would be the
code not working at all) but i will update this for the next version.

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

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

* Re: [Qemu-devel] [RFC v1 08/22] memory: provide defaults for MemoryListener operations
  2012-10-09 15:28         ` Avi Kivity
@ 2012-10-09 18:34           ` Anthony Liguori
  0 siblings, 0 replies; 70+ messages in thread
From: Anthony Liguori @ 2012-10-09 18:34 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Blue Swirl, Paolo Bonzini, Michael S. Tsirkin, qemu-devel, liu ping fan

Avi Kivity <avi@redhat.com> writes:

> On 10/09/2012 05:14 PM, Anthony Liguori wrote:
>>>> 
>>>> I think it'd be nicer to check for NULL when invoking the functions in
>>>> the memory core.
>>>> 
>>>> Then you avoid the exported stub functions entirely.
>>>
>>> Yes, that's the common style, but I happen not to like the extra check,
>>> both from a performance point of view (doesn't apply here of course) and
>>> from a readability point of view.
>> 
>> The trouble with your approach is that it introduced a subtle behavior
>> based on ordering.   IOW:
>> 
>> MemoryListenerOps foo = {
>>     MEMORY_LISTENER_DEFAULT_OPS,
>>     .log_sync = ...,
>> };
>> 
>> vs.
>> 
>> MemoryListenerOps foo = {
>>     .log_sync = ...,
>>     MEMORY_LISTENER_DEFAULT_OPS,
>> };
>> 
>> Both compile fine but have potentially difficult to debug differences.
>> Relying on zero-initialization eliminates the possibility of this problem.
>> 
>
> I don't think this is likely (esp. as the bad behaviour would be the
> code not working at all) but i will update this for the next version.

Thanks.  That's the only minor grip I had with the series.  It's really
a great cleanup!

Regards,

Anthony Liguori

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

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

end of thread, other threads:[~2012-10-09 18:35 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-03 16:03 [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 01/22] memory: rename 'exec-obsolete.h' Avi Kivity
2012-10-04 13:58   ` Anthony Liguori
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 02/22] vhost: use MemoryListener filtering to only monitor RAM address space Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 03/22] kvm: use separate MemoryListeners for memory and I/O Avi Kivity
2012-10-03 20:16   ` Blue Swirl
2012-10-04  6:33     ` Avi Kivity
2012-10-04 16:44       ` Blue Swirl
2012-10-04 16:58         ` Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 04/22] xen_pt: " Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 05/22] memory: prepare AddressSpace for exporting Avi Kivity
2012-10-04 14:01   ` Anthony Liguori
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 06/22] memory: export AddressSpace Avi Kivity
2012-10-04 14:02   ` Anthony Liguori
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 07/22] memory: maintain a list of address spaces Avi Kivity
2012-10-04 10:17   ` Gleb Natapov
2012-10-04 10:19     ` Avi Kivity
2012-10-04 14:03   ` Anthony Liguori
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 08/22] memory: provide defaults for MemoryListener operations Avi Kivity
2012-10-04 14:05   ` Anthony Liguori
2012-10-04 14:29     ` Avi Kivity
2012-10-09 15:14       ` Anthony Liguori
2012-10-09 15:28         ` Avi Kivity
2012-10-09 18:34           ` Anthony Liguori
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 09/22] memory: use new MEMORY_LISTENER_DEFAULT_OPS Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 10/22] vfio: " Avi Kivity
2012-10-04 15:45   ` Alex Williamson
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 11/22] xen_pt: " Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 12/22] kvm: " Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 13/22] xen: " Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 14/22] memory: manage coalesced mmio via a MemoryListener Avi Kivity
2012-10-04 14:08   ` Anthony Liguori
2012-10-04 14:33     ` Avi Kivity
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 15/22] memory: move address_space_memory and address_space_io out of memory core Avi Kivity
2012-10-04 14:08   ` Anthony Liguori
2012-10-03 16:03 ` [Qemu-devel] [RFC v1 16/22] memory: move tcg flush into a tcg memory listener Avi Kivity
2012-10-03 16:04 ` [Qemu-devel] [RFC v1 17/22] memory: use AddressSpace for MemoryListener filtering Avi Kivity
2012-10-03 20:16   ` Blue Swirl
2012-10-04 10:17     ` Avi Kivity
2012-10-04 16:57       ` Blue Swirl
2012-10-04 14:09   ` Anthony Liguori
2012-10-03 16:04 ` [Qemu-devel] [RFC v1 18/22] s390: avoid reaching into memory core internals Avi Kivity
2012-10-04  8:12   ` Christian Borntraeger
2012-10-03 16:04 ` [Qemu-devel] [RFC v1 19/22] memory: per-AddressSpace dispatch Avi Kivity
2012-10-03 20:24   ` Blue Swirl
2012-10-04  6:38     ` Avi Kivity
2012-10-04  8:47       ` Peter Maydell
2012-10-04 10:15         ` Avi Kivity
2012-10-04 10:29           ` Peter Maydell
2012-10-04 10:30             ` Avi Kivity
2012-10-04 17:13       ` Blue Swirl
2012-10-04 17:19         ` Avi Kivity
2012-10-04 17:42           ` Blue Swirl
2012-10-04 19:05             ` Anthony Liguori
2012-10-04 19:15               ` Blue Swirl
2012-10-04 19:16               ` Peter Maydell
2012-10-07 10:34                 ` Avi Kivity
2012-10-04 14:13   ` Anthony Liguori
2012-10-04 14:43     ` Avi Kivity
2012-10-09 15:17       ` Anthony Liguori
2012-10-03 16:04 ` [Qemu-devel] [RFC v1 20/22] dma: make dma access its own address space Avi Kivity
2012-10-04 14:15   ` Anthony Liguori
2012-10-03 16:04 ` [Qemu-devel] [RFC v1 21/22] pci: give each device " Avi Kivity
2012-10-03 16:04 ` [Qemu-devel] [RFC v1 22/22] pci: honor PCI_COMMAND_MASTER Avi Kivity
2012-10-03 20:26 ` [Qemu-devel] [RFC v1 00/22] Integrate DMA into the memory API Blue Swirl
2012-10-04 10:18   ` Avi Kivity
2012-10-04  6:41 ` Avi Kivity
2012-10-04  8:13 ` Paolo Bonzini
2012-10-04 14:16   ` Anthony Liguori
2012-10-04 14:36     ` Avi Kivity

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