qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps
@ 2012-02-08 15:27 Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 01/10] ioport: change portio_list not to use memory_region_set_offset() Avi Kivity
                   ` (11 more replies)
  0 siblings, 12 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

This patchset makes the memory core (memory.c) talk to the backend (in exec.c)
via a MemoryListener instead of named functions.

While the motivation for this is to simplify the memory core, it also enables
optimizing accelerators some more (by having a tcg MemoryListener to do tcg
specific core) and allows unit testing of memory.c (by adding a testing
MemoryListener and seeing what it outputs as various inputs are fed into the
core).

Avi Kivity (10):
  ioport: change portio_list not to use memory_region_set_offset()
  memory: remove memory_region_set_offset()
  memory: add shorthand for invoking a callback on all listeners
  memory: switch memory listeners to a QTAILQ
  memory: code motion: move MEMORY_LISTENER_CALL()
  memory: move ioeventfd ops to MemoryListener
  memory: add a readonly attribute to MemoryRegionSection
  memory: don't pass ->readable attribute to
    cpu_register_physical_memory_log
  memory: use a MemoryListener for core memory map updates too
  memory: drop AddressSpaceOps

 exec-obsolete.h |    5 +-
 exec.c          |   77 +++++++++++++++-
 hw/vhost.c      |   15 +++
 ioport.c        |   25 ++++-
 ioport.h        |    1 +
 kvm-all.c       |   79 +++++++++++++++
 memory.c        |  288 ++++++++++++++++++-------------------------------------
 memory.h        |   19 ++--
 xen-all.c       |   15 +++
 9 files changed, 310 insertions(+), 214 deletions(-)

-- 
1.7.9

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

* [Qemu-devel] [PATCH 01/10] ioport: change portio_list not to use memory_region_set_offset()
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 02/10] memory: remove memory_region_set_offset() Avi Kivity
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

memory_region_set_offset() will be going away soon, so don't use it.
Use an alias instead.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 ioport.c |   25 +++++++++++++++++++------
 ioport.h |    1 +
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/ioport.c b/ioport.c
index 36fa3a4..505b252 100644
--- a/ioport.c
+++ b/ioport.c
@@ -328,6 +328,7 @@ void portio_list_init(PortioList *piolist,
     piolist->ports = callbacks;
     piolist->nr = 0;
     piolist->regions = g_new0(MemoryRegion *, n);
+    piolist->aliases = g_new0(MemoryRegion *, n);
     piolist->address_space = NULL;
     piolist->opaque = opaque;
     piolist->name = name;
@@ -336,6 +337,7 @@ void portio_list_init(PortioList *piolist,
 void portio_list_destroy(PortioList *piolist)
 {
     g_free(piolist->regions);
+    g_free(piolist->aliases);
 }
 
 static void portio_list_add_1(PortioList *piolist,
@@ -345,7 +347,7 @@ static void portio_list_add_1(PortioList *piolist,
 {
     MemoryRegionPortio *pio;
     MemoryRegionOps *ops;
-    MemoryRegion *region;
+    MemoryRegion *region, *alias;
     unsigned i;
 
     /* Copy the sub-list and null-terminate it.  */
@@ -362,12 +364,19 @@ static void portio_list_add_1(PortioList *piolist,
     ops->old_portio = pio;
 
     region = g_new(MemoryRegion, 1);
+    alias = g_new(MemoryRegion, 1);
+    /*
+     * Use an alias so that the callback is called with an absolute address,
+     * rather than an offset relative to to start + off_low.
+     */
     memory_region_init_io(region, ops, piolist->opaque, piolist->name,
-                          off_high - off_low);
-    memory_region_set_offset(region, start + off_low);
+                          UINT64_MAX);
+    memory_region_init_alias(alias, piolist->name,
+                             region, start + off_low, off_high - off_low);
     memory_region_add_subregion(piolist->address_space,
-                                start + off_low, region);
+                                start + off_low, alias);
     piolist->regions[piolist->nr++] = region;
+    piolist->aliases[piolist->nr++] = alias;
 }
 
 void portio_list_add(PortioList *piolist,
@@ -409,15 +418,19 @@ void portio_list_add(PortioList *piolist,
 
 void portio_list_del(PortioList *piolist)
 {
-    MemoryRegion *mr;
+    MemoryRegion *mr, *alias;
     unsigned i;
 
     for (i = 0; i < piolist->nr; ++i) {
         mr = piolist->regions[i];
-        memory_region_del_subregion(piolist->address_space, mr);
+        alias = piolist->aliases[i];
+        memory_region_del_subregion(piolist->address_space, alias);
+        memory_region_destroy(alias);
         memory_region_destroy(mr);
         g_free((MemoryRegionOps *)mr->ops);
         g_free(mr);
+        g_free(alias);
         piolist->regions[i] = NULL;
+        piolist->aliases[i] = NULL;
     }
 }
diff --git a/ioport.h b/ioport.h
index ae3e9da..ab29c89 100644
--- a/ioport.h
+++ b/ioport.h
@@ -60,6 +60,7 @@ typedef struct PortioList {
     struct MemoryRegion *address_space;
     unsigned nr;
     struct MemoryRegion **regions;
+    struct MemoryRegion **aliases;
     void *opaque;
     const char *name;
 } PortioList;
-- 
1.7.9

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

* [Qemu-devel] [PATCH 02/10] memory: remove memory_region_set_offset()
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 01/10] ioport: change portio_list not to use memory_region_set_offset() Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 03/10] memory: add shorthand for invoking a callback on all listeners Avi Kivity
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

memory_region_set_offset() complicates the API, and has been deprecated
since its introduction.  Now that it is no longer used, remove it.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   26 ++++++++++----------------
 memory.h |    9 ---------
 2 files changed, 10 insertions(+), 25 deletions(-)

diff --git a/memory.c b/memory.c
index 5e77d8a..382dded 100644
--- a/memory.c
+++ b/memory.c
@@ -401,17 +401,17 @@ static void memory_region_iorange_read(IORange *iorange,
 
         *data = ((uint64_t)1 << (width * 8)) - 1;
         if (mrp) {
-            *data = mrp->read(mr->opaque, offset + mr->offset);
+            *data = mrp->read(mr->opaque, offset);
         } else if (width == 2) {
             mrp = find_portio(mr, offset, 1, false);
             assert(mrp);
-            *data = mrp->read(mr->opaque, offset + mr->offset) |
-                    (mrp->read(mr->opaque, offset + mr->offset + 1) << 8);
+            *data = mrp->read(mr->opaque, offset) |
+                    (mrp->read(mr->opaque, offset + 1) << 8);
         }
         return;
     }
     *data = 0;
-    access_with_adjusted_size(offset + mr->offset, data, width,
+    access_with_adjusted_size(offset, data, width,
                               mr->ops->impl.min_access_size,
                               mr->ops->impl.max_access_size,
                               memory_region_read_accessor, mr);
@@ -428,16 +428,16 @@ static void memory_region_iorange_write(IORange *iorange,
         const MemoryRegionPortio *mrp = find_portio(mr, offset, width, true);
 
         if (mrp) {
-            mrp->write(mr->opaque, offset + mr->offset, data);
+            mrp->write(mr->opaque, offset, data);
         } else if (width == 2) {
             mrp = find_portio(mr, offset, 1, false);
             assert(mrp);
-            mrp->write(mr->opaque, offset + mr->offset, data & 0xff);
-            mrp->write(mr->opaque, offset + mr->offset + 1, data >> 8);
+            mrp->write(mr->opaque, offset, data & 0xff);
+            mrp->write(mr->opaque, offset + 1, data >> 8);
         }
         return;
     }
-    access_with_adjusted_size(offset + mr->offset, &data, width,
+    access_with_adjusted_size(offset, &data, width,
                               mr->ops->impl.min_access_size,
                               mr->ops->impl.max_access_size,
                               memory_region_write_accessor, mr);
@@ -863,7 +863,6 @@ void memory_region_init(MemoryRegion *mr,
         mr->size = int128_2_64();
     }
     mr->addr = 0;
-    mr->offset = 0;
     mr->subpage = false;
     mr->enabled = true;
     mr->terminates = false;
@@ -925,7 +924,7 @@ static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,
     }
 
     /* FIXME: support unaligned access */
-    access_with_adjusted_size(addr + mr->offset, &data, size,
+    access_with_adjusted_size(addr, &data, size,
                               mr->ops->impl.min_access_size,
                               mr->ops->impl.max_access_size,
                               memory_region_read_accessor, mr);
@@ -979,7 +978,7 @@ static void memory_region_dispatch_write(MemoryRegion *mr,
     }
 
     /* FIXME: support unaligned access */
-    access_with_adjusted_size(addr + mr->offset, &data, size,
+    access_with_adjusted_size(addr, &data, size,
                               mr->ops->impl.min_access_size,
                               mr->ops->impl.max_access_size,
                               memory_region_write_accessor, mr);
@@ -1122,11 +1121,6 @@ bool memory_region_is_rom(MemoryRegion *mr)
     return mr->ram && mr->readonly;
 }
 
-void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset)
-{
-    mr->offset = offset;
-}
-
 void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
 {
     uint8_t mask = 1 << client;
diff --git a/memory.h b/memory.h
index 4cf8d2f..4763286 100644
--- a/memory.h
+++ b/memory.h
@@ -115,7 +115,6 @@ struct MemoryRegion {
     MemoryRegion *parent;
     Int128 size;
     target_phys_addr_t addr;
-    target_phys_addr_t offset;
     void (*destructor)(MemoryRegion *mr);
     ram_addr_t ram_addr;
     IORange iorange;
@@ -359,14 +358,6 @@ bool memory_region_is_rom(MemoryRegion *mr);
 void *memory_region_get_ram_ptr(MemoryRegion *mr);
 
 /**
- * memory_region_set_offset: Sets an offset to be added to MemoryRegionOps
- *                           callbacks.
- *
- * This function is deprecated and should not be used in new code.
- */
-void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset);
-
-/**
  * memory_region_set_log: Turn dirty logging on or off for a region.
  *
  * Turns dirty logging on or off for a specified client (display, migration).
-- 
1.7.9

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

* [Qemu-devel] [PATCH 03/10] memory: add shorthand for invoking a callback on all listeners
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 01/10] ioport: change portio_list not to use memory_region_set_offset() Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 02/10] memory: remove memory_region_set_offset() Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 04/10] memory: switch memory listeners to a QTAILQ Avi Kivity
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   54 +++++++++++++++++++-----------------------------------
 1 files changed, 19 insertions(+), 35 deletions(-)

diff --git a/memory.c b/memory.c
index 382dded..6afe414 100644
--- a/memory.c
+++ b/memory.c
@@ -678,31 +678,23 @@ static void address_space_update_ioeventfds(AddressSpace *as)
     as->ioeventfd_nb = ioeventfd_nb;
 }
 
-typedef void ListenerCallback(MemoryListener *listener,
-                              MemoryRegionSection *mrs);
-
-/* Want "void (&MemoryListener::*callback)(const MemoryRegionSection& s)" */
-static void memory_listener_update_region(FlatRange *fr, AddressSpace *as,
-                                          size_t callback_offset)
-{
-    MemoryRegionSection section = {
-        .mr = fr->mr,
-        .address_space = as->root,
-        .offset_within_region = fr->offset_in_region,
-        .size = int128_get64(fr->addr.size),
-        .offset_within_address_space = int128_get64(fr->addr.start),
-    };
-    MemoryListener *listener;
-
-    QLIST_FOREACH(listener, &memory_listeners, link) {
-        ListenerCallback *callback
-            = *(ListenerCallback **)((void *)listener + callback_offset);
-        callback(listener, &section);
-    }
-}
-
-#define MEMORY_LISTENER_UPDATE_REGION(fr, as, callback) \
-    memory_listener_update_region(fr, as, offsetof(MemoryListener, callback))
+#define MEMORY_LISTENER_CALL(_callback, _args...)               \
+    do {                                                        \
+        MemoryListener *_listener;                              \
+                                                                \
+        QLIST_FOREACH(_listener, &memory_listeners, link) {     \
+            _listener->_callback(_listener, ##_args);           \
+        }                                                       \
+    } while (0)
+
+#define MEMORY_LISTENER_UPDATE_REGION(fr, as, callback)                 \
+    MEMORY_LISTENER_CALL(callback, &(MemoryRegionSection) {             \
+        .mr = (fr)->mr,                                                 \
+        .address_space = (as)->root,                                    \
+        .offset_within_region = (fr)->offset_in_region,                 \
+        .size = int128_get64((fr)->addr.size),                          \
+        .offset_within_address_space = int128_get64((fr)->addr.start),  \
+                })
 
 static void address_space_update_topology_pass(AddressSpace *as,
                                                FlatView old_view,
@@ -1483,23 +1475,15 @@ void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
 
 void memory_global_dirty_log_start(void)
 {
-    MemoryListener *listener;
-
     cpu_physical_memory_set_dirty_tracking(1);
     global_dirty_log = true;
-    QLIST_FOREACH(listener, &memory_listeners, link) {
-        listener->log_global_start(listener);
-    }
+    MEMORY_LISTENER_CALL(log_global_start);
 }
 
 void memory_global_dirty_log_stop(void)
 {
-    MemoryListener *listener;
-
     global_dirty_log = false;
-    QLIST_FOREACH(listener, &memory_listeners, link) {
-        listener->log_global_stop(listener);
-    }
+    MEMORY_LISTENER_CALL(log_global_stop);
     cpu_physical_memory_set_dirty_tracking(0);
 }
 
-- 
1.7.9

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

* [Qemu-devel] [PATCH 04/10] memory: switch memory listeners to a QTAILQ
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (2 preceding siblings ...)
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 03/10] memory: add shorthand for invoking a callback on all listeners Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 05/10] memory: code motion: move MEMORY_LISTENER_CALL() Avi Kivity
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

This allows reverse iteration, which in turns allows consistent ordering
among multiple listeners:

  l1->add
  l2->add
  l2->del
  l1->del

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/vhost.c |    1 +
 kvm-all.c  |    1 +
 memory.c   |   70 ++++++++++++++++++++++++++++++++++++++++++------------------
 memory.h   |    4 ++-
 xen-all.c  |    1 +
 5 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/hw/vhost.c b/hw/vhost.c
index 5ece659..4737145 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -751,6 +751,7 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force)
         .log_sync = vhost_log_sync,
         .log_global_start = vhost_log_global_start,
         .log_global_stop = vhost_log_global_stop,
+        .priority = 10
     };
     hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions));
     hdev->n_mem_sections = 0;
diff --git a/kvm-all.c b/kvm-all.c
index 0b87658..6835fd4 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -726,6 +726,7 @@ static void kvm_log_global_stop(struct MemoryListener *listener)
     .log_sync = kvm_log_sync,
     .log_global_start = kvm_log_global_start,
     .log_global_stop = kvm_log_global_stop,
+    .priority = 10,
 };
 
 static void kvm_handle_interrupt(CPUState *env, int mask)
diff --git a/memory.c b/memory.c
index 6afe414..cb2b4f1 100644
--- a/memory.c
+++ b/memory.c
@@ -27,8 +27,8 @@
 static bool memory_region_update_pending = false;
 static bool global_dirty_log = false;
 
-static QLIST_HEAD(, MemoryListener) memory_listeners
-    = QLIST_HEAD_INITIALIZER(memory_listeners);
+static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
+    = QTAILQ_HEAD_INITIALIZER(memory_listeners);
 
 typedef struct AddrRange AddrRange;
 
@@ -678,17 +678,31 @@ static void address_space_update_ioeventfds(AddressSpace *as)
     as->ioeventfd_nb = ioeventfd_nb;
 }
 
-#define MEMORY_LISTENER_CALL(_callback, _args...)               \
-    do {                                                        \
-        MemoryListener *_listener;                              \
-                                                                \
-        QLIST_FOREACH(_listener, &memory_listeners, link) {     \
-            _listener->_callback(_listener, ##_args);           \
-        }                                                       \
+enum ListenerDirection { Forward, Reverse };
+
+#define MEMORY_LISTENER_CALL(_callback, _direction, _args...)           \
+    do {                                                                \
+        MemoryListener *_listener;                                      \
+                                                                        \
+        switch (_direction) {                                           \
+        case Forward:                                                   \
+            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
+                _listener->_callback(_listener, ##_args);               \
+            }                                                           \
+            break;                                                      \
+        case Reverse:                                                   \
+            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
+                                   memory_listeners, link) {            \
+                _listener->_callback(_listener, ##_args);               \
+            }                                                           \
+            break;                                                      \
+        default:                                                        \
+            abort();                                                    \
+        }                                                               \
     } while (0)
 
-#define MEMORY_LISTENER_UPDATE_REGION(fr, as, callback)                 \
-    MEMORY_LISTENER_CALL(callback, &(MemoryRegionSection) {             \
+#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
+    MEMORY_LISTENER_CALL(callback, dir, &(MemoryRegionSection) {        \
         .mr = (fr)->mr,                                                 \
         .address_space = (as)->root,                                    \
         .offset_within_region = (fr)->offset_in_region,                 \
@@ -728,7 +742,7 @@ static void address_space_update_topology_pass(AddressSpace *as,
             /* In old, but (not in new, or in new but attributes changed). */
 
             if (!adding) {
-                MEMORY_LISTENER_UPDATE_REGION(frold, as, region_del);
+                MEMORY_LISTENER_UPDATE_REGION(frold, as, Reverse, region_del);
                 as->ops->range_del(as, frold);
             }
 
@@ -738,11 +752,11 @@ static void address_space_update_topology_pass(AddressSpace *as,
 
             if (adding) {
                 if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
-                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, log_stop);
+                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse, log_stop);
                     as->ops->log_stop(as, frnew);
                 } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
                     as->ops->log_start(as, frnew);
-                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, log_start);
+                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start);
                 }
             }
 
@@ -753,7 +767,7 @@ static void address_space_update_topology_pass(AddressSpace *as,
 
             if (adding) {
                 as->ops->range_add(as, frnew);
-                MEMORY_LISTENER_UPDATE_REGION(frnew, as, region_add);
+                MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_add);
             }
 
             ++inew;
@@ -1142,7 +1156,8 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 
     FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
         if (fr->mr == mr) {
-            MEMORY_LISTENER_UPDATE_REGION(fr, &address_space_memory, log_sync);
+            MEMORY_LISTENER_UPDATE_REGION(fr, &address_space_memory,
+                                          Forward, log_sync);
         }
     }
 }
@@ -1469,7 +1484,7 @@ void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
     FlatRange *fr;
 
     FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
-        MEMORY_LISTENER_UPDATE_REGION(fr, as, log_sync);
+        MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
     }
 }
 
@@ -1477,13 +1492,13 @@ void memory_global_dirty_log_start(void)
 {
     cpu_physical_memory_set_dirty_tracking(1);
     global_dirty_log = true;
-    MEMORY_LISTENER_CALL(log_global_start);
+    MEMORY_LISTENER_CALL(log_global_start, Forward);
 }
 
 void memory_global_dirty_log_stop(void)
 {
     global_dirty_log = false;
-    MEMORY_LISTENER_CALL(log_global_stop);
+    MEMORY_LISTENER_CALL(log_global_stop, Reverse);
     cpu_physical_memory_set_dirty_tracking(0);
 }
 
@@ -1509,14 +1524,27 @@ static void listener_add_address_space(MemoryListener *listener,
 
 void memory_listener_register(MemoryListener *listener)
 {
-    QLIST_INSERT_HEAD(&memory_listeners, listener, link);
+    MemoryListener *other = NULL;
+
+    if (QTAILQ_EMPTY(&memory_listeners)
+        || listener->priority >= QTAILQ_LAST(&memory_listeners,
+                                             memory_listeners)->priority) {
+        QTAILQ_INSERT_TAIL(&memory_listeners, listener, link);
+    } else {
+        QTAILQ_FOREACH(other, &memory_listeners, link) {
+            if (listener->priority < other->priority) {
+                break;
+            }
+        }
+        QTAILQ_INSERT_BEFORE(other, listener, link);
+    }
     listener_add_address_space(listener, &address_space_memory);
     listener_add_address_space(listener, &address_space_io);
 }
 
 void memory_listener_unregister(MemoryListener *listener)
 {
-    QLIST_REMOVE(listener, link);
+    QTAILQ_REMOVE(&memory_listeners, listener, link);
 }
 
 void set_system_memory_map(MemoryRegion *mr)
diff --git a/memory.h b/memory.h
index 4763286..954dc86 100644
--- a/memory.h
+++ b/memory.h
@@ -185,7 +185,9 @@ struct MemoryListener {
     void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section);
     void (*log_global_start)(MemoryListener *listener);
     void (*log_global_stop)(MemoryListener *listener);
-    QLIST_ENTRY(MemoryListener) link;
+    /* Lower = earlier (during add), later (during del) */
+    unsigned priority;
+    QTAILQ_ENTRY(MemoryListener) link;
 };
 
 /**
diff --git a/xen-all.c b/xen-all.c
index fd39168..8cb84ef 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -495,6 +495,7 @@ static void xen_log_global_stop(MemoryListener *listener)
     .log_sync = xen_log_sync,
     .log_global_start = xen_log_global_start,
     .log_global_stop = xen_log_global_stop,
+    .priority = 10,
 };
 
 /* VCPU Operations, MMIO, IO ring ... */
-- 
1.7.9

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

* [Qemu-devel] [PATCH 05/10] memory: code motion: move MEMORY_LISTENER_CALL()
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (3 preceding siblings ...)
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 04/10] memory: switch memory listeners to a QTAILQ Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 06/10] memory: move ioeventfd ops to MemoryListener Avi Kivity
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

So it can be used in earlier code.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   64 +++++++++++++++++++++++++++++++-------------------------------
 1 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/memory.c b/memory.c
index cb2b4f1..a1013bc 100644
--- a/memory.c
+++ b/memory.c
@@ -82,6 +82,38 @@ static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
     return addrrange_make(start, int128_sub(end, start));
 }
 
+enum ListenerDirection { Forward, Reverse };
+
+#define MEMORY_LISTENER_CALL(_callback, _direction, _args...)           \
+    do {                                                                \
+        MemoryListener *_listener;                                      \
+                                                                        \
+        switch (_direction) {                                           \
+        case Forward:                                                   \
+            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
+                _listener->_callback(_listener, ##_args);               \
+            }                                                           \
+            break;                                                      \
+        case Reverse:                                                   \
+            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
+                                   memory_listeners, link) {            \
+                _listener->_callback(_listener, ##_args);               \
+            }                                                           \
+            break;                                                      \
+        default:                                                        \
+            abort();                                                    \
+        }                                                               \
+    } while (0)
+
+#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
+    MEMORY_LISTENER_CALL(callback, dir, &(MemoryRegionSection) {        \
+        .mr = (fr)->mr,                                                 \
+        .address_space = (as)->root,                                    \
+        .offset_within_region = (fr)->offset_in_region,                 \
+        .size = int128_get64((fr)->addr.size),                          \
+        .offset_within_address_space = int128_get64((fr)->addr.start),  \
+                })
+
 struct CoalescedMemoryRange {
     AddrRange addr;
     QTAILQ_ENTRY(CoalescedMemoryRange) link;
@@ -678,38 +710,6 @@ static void address_space_update_ioeventfds(AddressSpace *as)
     as->ioeventfd_nb = ioeventfd_nb;
 }
 
-enum ListenerDirection { Forward, Reverse };
-
-#define MEMORY_LISTENER_CALL(_callback, _direction, _args...)           \
-    do {                                                                \
-        MemoryListener *_listener;                                      \
-                                                                        \
-        switch (_direction) {                                           \
-        case Forward:                                                   \
-            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
-                _listener->_callback(_listener, ##_args);               \
-            }                                                           \
-            break;                                                      \
-        case Reverse:                                                   \
-            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
-                                   memory_listeners, link) {            \
-                _listener->_callback(_listener, ##_args);               \
-            }                                                           \
-            break;                                                      \
-        default:                                                        \
-            abort();                                                    \
-        }                                                               \
-    } while (0)
-
-#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
-    MEMORY_LISTENER_CALL(callback, dir, &(MemoryRegionSection) {        \
-        .mr = (fr)->mr,                                                 \
-        .address_space = (as)->root,                                    \
-        .offset_within_region = (fr)->offset_in_region,                 \
-        .size = int128_get64((fr)->addr.size),                          \
-        .offset_within_address_space = int128_get64((fr)->addr.start),  \
-                })
-
 static void address_space_update_topology_pass(AddressSpace *as,
                                                FlatView old_view,
                                                FlatView new_view,
-- 
1.7.9

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

* [Qemu-devel] [PATCH 06/10] memory: move ioeventfd ops to MemoryListener
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (4 preceding siblings ...)
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 05/10] memory: code motion: move MEMORY_LISTENER_CALL() Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 07/10] memory: add a readonly attribute to MemoryRegionSection Avi Kivity
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

This way the accelerator (kvm) can handle them directly.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/vhost.c |   14 ++++++++++
 kvm-all.c  |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.c   |   74 ++++++++++++++-------------------------------------------
 memory.h   |    4 +++
 xen-all.c  |   14 ++++++++++
 5 files changed, 128 insertions(+), 56 deletions(-)

diff --git a/hw/vhost.c b/hw/vhost.c
index 4737145..e1e7e01 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -720,6 +720,18 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev,
                               0, virtio_queue_get_desc_size(vdev, idx));
 }
 
+static void vhost_eventfd_add(MemoryListener *listener,
+                              MemoryRegionSection *section,
+                              bool match_data, uint64_t data, int fd)
+{
+}
+
+static void vhost_eventfd_del(MemoryListener *listener,
+                              MemoryRegionSection *section,
+                              bool match_data, uint64_t data, int fd)
+{
+}
+
 int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force)
 {
     uint64_t features;
@@ -751,6 +763,8 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force)
         .log_sync = vhost_log_sync,
         .log_global_start = vhost_log_global_start,
         .log_global_stop = vhost_log_global_stop,
+        .eventfd_add = vhost_eventfd_add,
+        .eventfd_del = vhost_eventfd_del,
         .priority = 10
     };
     hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions));
diff --git a/kvm-all.c b/kvm-all.c
index 6835fd4..a05e591 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -28,6 +28,7 @@
 #include "kvm.h"
 #include "bswap.h"
 #include "memory.h"
+#include "exec-memory.h"
 
 /* This check must be after config-host.h is included */
 #ifdef CONFIG_EVENTFD
@@ -718,6 +719,81 @@ 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)
+{
+    int r;
+
+    assert(match_data && section->size == 4);
+
+    r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space,
+                                    data, true);
+    if (r < 0) {
+        abort();
+    }
+}
+
+static void kvm_mem_ioeventfd_del(MemoryRegionSection *section,
+                                  bool match_data, uint64_t data, int fd)
+{
+    int r;
+
+    r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space,
+                                    data, false);
+    if (r < 0) {
+        abort();
+    }
+}
+
+static void kvm_io_ioeventfd_add(MemoryRegionSection *section,
+                                 bool match_data, uint64_t data, int fd)
+{
+    int r;
+
+    assert(match_data && section->size == 2);
+
+    r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
+                                   data, true);
+    if (r < 0) {
+        abort();
+    }
+}
+
+static void kvm_io_ioeventfd_del(MemoryRegionSection *section,
+                                 bool match_data, uint64_t data, int fd)
+
+{
+    int r;
+
+    r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
+                                   data, false);
+    if (r < 0) {
+        abort();
+    }
+}
+
+static void kvm_eventfd_add(MemoryListener *listener,
+                            MemoryRegionSection *section,
+                            bool match_data, uint64_t data, int fd)
+{
+    if (section->address_space == get_system_memory()) {
+        kvm_mem_ioeventfd_add(section, match_data, data, fd);
+    } else {
+        kvm_io_ioeventfd_add(section, match_data, data, fd);
+    }
+}
+
+static void kvm_eventfd_del(MemoryListener *listener,
+                            MemoryRegionSection *section,
+                            bool match_data, uint64_t data, int fd)
+{
+    if (section->address_space == get_system_memory()) {
+        kvm_mem_ioeventfd_del(section, match_data, data, fd);
+    } else {
+        kvm_io_ioeventfd_del(section, match_data, data, fd);
+    }
+}
+
 static MemoryListener kvm_memory_listener = {
     .region_add = kvm_region_add,
     .region_del = kvm_region_del,
@@ -726,6 +802,8 @@ static void kvm_log_global_stop(struct 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,
     .priority = 10,
 };
 
diff --git a/memory.c b/memory.c
index a1013bc..e1a31d4 100644
--- a/memory.c
+++ b/memory.c
@@ -202,8 +202,6 @@ struct AddressSpaceOps {
     void (*range_del)(AddressSpace *as, FlatRange *fr);
     void (*log_start)(AddressSpace *as, FlatRange *fr);
     void (*log_stop)(AddressSpace *as, FlatRange *fr);
-    void (*ioeventfd_add)(AddressSpace *as, MemoryRegionIoeventfd *fd);
-    void (*ioeventfd_del)(AddressSpace *as, MemoryRegionIoeventfd *fd);
 };
 
 #define FOR_EACH_FLAT_RANGE(var, view)          \
@@ -369,37 +367,11 @@ static void as_memory_log_stop(AddressSpace *as, FlatRange *fr)
 {
 }
 
-static void as_memory_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd)
-{
-    int r;
-
-    assert(fd->match_data && int128_get64(fd->addr.size) == 4);
-
-    r = kvm_set_ioeventfd_mmio_long(fd->fd, int128_get64(fd->addr.start),
-                                    fd->data, true);
-    if (r < 0) {
-        abort();
-    }
-}
-
-static void as_memory_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd)
-{
-    int r;
-
-    r = kvm_set_ioeventfd_mmio_long(fd->fd, int128_get64(fd->addr.start),
-                                    fd->data, false);
-    if (r < 0) {
-        abort();
-    }
-}
-
 static const AddressSpaceOps address_space_ops_memory = {
     .range_add = as_memory_range_add,
     .range_del = as_memory_range_del,
     .log_start = as_memory_log_start,
     .log_stop = as_memory_log_stop,
-    .ioeventfd_add = as_memory_ioeventfd_add,
-    .ioeventfd_del = as_memory_ioeventfd_del,
 };
 
 static AddressSpace address_space_memory = {
@@ -493,35 +465,9 @@ static void as_io_range_del(AddressSpace *as, FlatRange *fr)
                         int128_get64(fr->addr.size));
 }
 
-static void as_io_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd)
-{
-    int r;
-
-    assert(fd->match_data && int128_get64(fd->addr.size) == 2);
-
-    r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start),
-                                   fd->data, true);
-    if (r < 0) {
-        abort();
-    }
-}
-
-static void as_io_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd)
-{
-    int r;
-
-    r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start),
-                                   fd->data, false);
-    if (r < 0) {
-        abort();
-    }
-}
-
 static const AddressSpaceOps address_space_ops_io = {
     .range_add = as_io_range_add,
     .range_del = as_io_range_del,
-    .ioeventfd_add = as_io_ioeventfd_add,
-    .ioeventfd_del = as_io_ioeventfd_del,
 };
 
 static AddressSpace address_space_io = {
@@ -653,6 +599,8 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
                                              unsigned fds_old_nb)
 {
     unsigned iold, inew;
+    MemoryRegionIoeventfd *fd;
+    MemoryRegionSection section;
 
     /* Generate a symmetric difference of the old and new fd sets, adding
      * and deleting as necessary.
@@ -664,13 +612,27 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
             && (inew == fds_new_nb
                 || memory_region_ioeventfd_before(fds_old[iold],
                                                   fds_new[inew]))) {
-            as->ops->ioeventfd_del(as, &fds_old[iold]);
+            fd = &fds_old[iold];
+            section = (MemoryRegionSection) {
+                .address_space = as->root,
+                .offset_within_address_space = int128_get64(fd->addr.start),
+                .size = int128_get64(fd->addr.size),
+            };
+            MEMORY_LISTENER_CALL(eventfd_del, Forward, &section,
+                                 fd->match_data, fd->data, fd->fd);
             ++iold;
         } else if (inew < fds_new_nb
                    && (iold == fds_old_nb
                        || memory_region_ioeventfd_before(fds_new[inew],
                                                          fds_old[iold]))) {
-            as->ops->ioeventfd_add(as, &fds_new[inew]);
+            fd = &fds_new[inew];
+            section = (MemoryRegionSection) {
+                .address_space = as->root,
+                .offset_within_address_space = int128_get64(fd->addr.start),
+                .size = int128_get64(fd->addr.size),
+            };
+            MEMORY_LISTENER_CALL(eventfd_add, Reverse, &section,
+                                 fd->match_data, fd->data, fd->fd);
             ++inew;
         } else {
             ++iold;
diff --git a/memory.h b/memory.h
index 954dc86..84bb67c 100644
--- a/memory.h
+++ b/memory.h
@@ -185,6 +185,10 @@ struct MemoryListener {
     void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section);
     void (*log_global_start)(MemoryListener *listener);
     void (*log_global_stop)(MemoryListener *listener);
+    void (*eventfd_add)(MemoryListener *listener, MemoryRegionSection *section,
+                        bool match_data, uint64_t data, int fd);
+    void (*eventfd_del)(MemoryListener *listener, MemoryRegionSection *section,
+                        bool match_data, uint64_t data, int fd);
     /* Lower = earlier (during add), later (during del) */
     unsigned priority;
     QTAILQ_ENTRY(MemoryListener) link;
diff --git a/xen-all.c b/xen-all.c
index 8cb84ef..e005b63 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -487,6 +487,18 @@ static void xen_log_global_stop(MemoryListener *listener)
 {
 }
 
+static void xen_eventfd_add(MemoryListener *listener,
+                            MemoryRegionSection *section,
+                            bool match_data, uint64_t data, int fd)
+{
+}
+
+static void xen_eventfd_del(MemoryListener *listener,
+                            MemoryRegionSection *section,
+                            bool match_data, uint64_t data, int fd)
+{
+}
+
 static MemoryListener xen_memory_listener = {
     .region_add = xen_region_add,
     .region_del = xen_region_del,
@@ -495,6 +507,8 @@ static void xen_log_global_stop(MemoryListener *listener)
     .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.9

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

* [Qemu-devel] [PATCH 07/10] memory: add a readonly attribute to MemoryRegionSection
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (5 preceding siblings ...)
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 06/10] memory: move ioeventfd ops to MemoryListener Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 08/10] memory: don't pass ->readable attribute to cpu_register_physical_memory_log Avi Kivity
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

.readonly cannot be obtained from the MemoryRegion, since it is
inherited from aliases (so you can have a MemoryRegion mapped RW
at one address and RO at another).  Record it in a MemoryRegionSection
for listeners.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |    5 +++++
 memory.h |    2 ++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index e1a31d4..4f37152 100644
--- a/memory.c
+++ b/memory.c
@@ -112,6 +112,7 @@ static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
         .offset_within_region = (fr)->offset_in_region,                 \
         .size = int128_get64((fr)->addr.size),                          \
         .offset_within_address_space = int128_get64((fr)->addr.start),  \
+        .readonly = (fr)->readonly,                                     \
                 })
 
 struct CoalescedMemoryRange {
@@ -342,6 +343,7 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
         .offset_within_address_space = int128_get64(fr->addr.start),
         .offset_within_region = fr->offset_in_region,
         .size = int128_get64(fr->addr.size),
+        .readonly = fr->readonly,
     };
 
     cpu_register_physical_memory_log(&section, fr->readable, fr->readonly);
@@ -354,6 +356,7 @@ static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
         .offset_within_address_space = int128_get64(fr->addr.start),
         .offset_within_region = int128_get64(fr->addr.start),
         .size = int128_get64(fr->addr.size),
+        .readonly = fr->readonly,
     };
 
     cpu_register_physical_memory_log(&section, true, false);
@@ -1437,6 +1440,7 @@ MemoryRegionSection memory_region_find(MemoryRegion *address_space,
                                                         fr->addr.start));
     ret.size = int128_get64(range.size);
     ret.offset_within_address_space = int128_get64(range.start);
+    ret.readonly = fr->readonly;
     return ret;
 }
 
@@ -1479,6 +1483,7 @@ static void listener_add_address_space(MemoryListener *listener,
             .offset_within_region = fr->offset_in_region,
             .size = int128_get64(fr->addr.size),
             .offset_within_address_space = int128_get64(fr->addr.start),
+            .readonly = fr->readonly,
         };
         listener->region_add(listener, &section);
     }
diff --git a/memory.h b/memory.h
index 84bb67c..1d99cee 100644
--- a/memory.h
+++ b/memory.h
@@ -160,6 +160,7 @@ typedef struct MemoryRegionSection MemoryRegionSection;
  * @size: the size of the section; will not exceed @mr's boundaries
  * @offset_within_address_space: the address of the first byte of the section
  *     relative to the region's address space
+ * @readonly: writes to this section are ignored
  */
 struct MemoryRegionSection {
     MemoryRegion *mr;
@@ -167,6 +168,7 @@ struct MemoryRegionSection {
     target_phys_addr_t offset_within_region;
     uint64_t size;
     target_phys_addr_t offset_within_address_space;
+    bool readonly;
 };
 
 typedef struct MemoryListener MemoryListener;
-- 
1.7.9

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

* [Qemu-devel] [PATCH 08/10] memory: don't pass ->readable attribute to cpu_register_physical_memory_log
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (6 preceding siblings ...)
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 07/10] memory: add a readonly attribute to MemoryRegionSection Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 09/10] memory: use a MemoryListener for core memory map updates too Avi Kivity
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

It can be derived from the MemoryRegion itself (which is why it is not
used there).

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-obsolete.h |    2 +-
 exec.c          |    2 +-
 memory.c        |    4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/exec-obsolete.h b/exec-obsolete.h
index 94c23d0..23ffbaa 100644
--- a/exec-obsolete.h
+++ b/exec-obsolete.h
@@ -37,7 +37,7 @@ void cpu_unregister_io_memory(int table_address);
 
 struct MemoryRegionSection;
 void cpu_register_physical_memory_log(struct MemoryRegionSection *section,
-                                      bool readable, bool readonly);
+                                      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/exec.c b/exec.c
index b81677a..d3020ab 100644
--- a/exec.c
+++ b/exec.c
@@ -2529,7 +2529,7 @@ static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
    before calculating this offset.  This should not be a problem unless
    the low bits of start_addr and region_offset differ.  */
 void cpu_register_physical_memory_log(MemoryRegionSection *section,
-                                      bool readable, bool readonly)
+                                      bool readonly)
 {
     target_phys_addr_t start_addr = section->offset_within_address_space;
     ram_addr_t size = section->size;
diff --git a/memory.c b/memory.c
index 4f37152..71039c4 100644
--- a/memory.c
+++ b/memory.c
@@ -346,7 +346,7 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
         .readonly = fr->readonly,
     };
 
-    cpu_register_physical_memory_log(&section, fr->readable, fr->readonly);
+    cpu_register_physical_memory_log(&section, fr->readonly);
 }
 
 static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
@@ -359,7 +359,7 @@ static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
         .readonly = fr->readonly,
     };
 
-    cpu_register_physical_memory_log(&section, true, false);
+    cpu_register_physical_memory_log(&section, false);
 }
 
 static void as_memory_log_start(AddressSpace *as, FlatRange *fr)
-- 
1.7.9

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

* [Qemu-devel] [PATCH 09/10] memory: use a MemoryListener for core memory map updates too
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (7 preceding siblings ...)
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 08/10] memory: don't pass ->readable attribute to cpu_register_physical_memory_log Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-09  7:58   ` Paolo Bonzini
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 10/10] memory: drop AddressSpaceOps Avi Kivity
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

This transforms memory.c into a library which can then be unit tested
easily, by feeding it inputs and listening to its outputs.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-obsolete.h |    3 ++
 exec.c          |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.c        |   27 +-------------------
 3 files changed, 79 insertions(+), 26 deletions(-)

diff --git a/exec-obsolete.h b/exec-obsolete.h
index 23ffbaa..4dbe476 100644
--- a/exec-obsolete.h
+++ b/exec-obsolete.h
@@ -121,6 +121,9 @@ static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,
 
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
                                      int dirty_flags);
+
+extern const IORangeOps memory_region_iorange_ops;
+
 #endif
 
 #endif
diff --git a/exec.c b/exec.c
index d3020ab..7fb5d4e 100644
--- a/exec.c
+++ b/exec.c
@@ -3488,6 +3488,79 @@ static void io_mem_init(void)
                           "watch", UINT64_MAX);
 }
 
+static void core_region_add(MemoryListener *listener,
+                            MemoryRegionSection *section)
+{
+    if (section->address_space == get_system_memory()) {
+        cpu_register_physical_memory_log(section, section->readonly);
+    } else {
+        iorange_init(&section->mr->iorange, &memory_region_iorange_ops,
+                     section->offset_within_address_space, section->size);
+        ioport_register(&section->mr->iorange);
+    }
+}
+
+static void core_region_del(MemoryListener *listener,
+                            MemoryRegionSection *section)
+{
+    if (section->address_space == get_system_memory()) {
+        cpu_register_physical_memory_log(section, false);
+    } else {
+        isa_unassign_ioport(section->offset_within_address_space,
+                            section->size);
+    }
+}
+
+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);
+}
+
+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, int fd)
+{
+}
+
+static void core_eventfd_del(MemoryListener *listener,
+                             MemoryRegionSection *section,
+                             bool match_data, uint64_t data, int fd)
+{
+}
+
+static MemoryListener core_memory_listener = {
+    .region_add = core_region_add,
+    .region_del = core_region_del,
+    .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 void memory_map_init(void)
 {
     system_memory = g_malloc(sizeof(*system_memory));
@@ -3497,6 +3570,8 @@ static void memory_map_init(void)
     system_io = g_malloc(sizeof(*system_io));
     memory_region_init(system_io, "io", 65536);
     set_system_io_map(system_io);
+
+    memory_listener_register(&core_memory_listener);
 }
 
 MemoryRegion *get_system_memory(void)
diff --git a/memory.c b/memory.c
index 71039c4..4e7a90b 100644
--- a/memory.c
+++ b/memory.c
@@ -338,28 +338,10 @@ static void access_with_adjusted_size(target_phys_addr_t addr,
 
 static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
 {
-    MemoryRegionSection section = {
-        .mr = fr->mr,
-        .offset_within_address_space = int128_get64(fr->addr.start),
-        .offset_within_region = fr->offset_in_region,
-        .size = int128_get64(fr->addr.size),
-        .readonly = fr->readonly,
-    };
-
-    cpu_register_physical_memory_log(&section, fr->readonly);
 }
 
 static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
 {
-    MemoryRegionSection section = {
-        .mr = &io_mem_unassigned,
-        .offset_within_address_space = int128_get64(fr->addr.start),
-        .offset_within_region = int128_get64(fr->addr.start),
-        .size = int128_get64(fr->addr.size),
-        .readonly = fr->readonly,
-    };
-
-    cpu_register_physical_memory_log(&section, false);
 }
 
 static void as_memory_log_start(AddressSpace *as, FlatRange *fr)
@@ -450,22 +432,17 @@ static void memory_region_iorange_write(IORange *iorange,
                               memory_region_write_accessor, mr);
 }
 
-static const IORangeOps memory_region_iorange_ops = {
+const IORangeOps memory_region_iorange_ops = {
     .read = memory_region_iorange_read,
     .write = memory_region_iorange_write,
 };
 
 static void as_io_range_add(AddressSpace *as, FlatRange *fr)
 {
-    iorange_init(&fr->mr->iorange, &memory_region_iorange_ops,
-                 int128_get64(fr->addr.start), int128_get64(fr->addr.size));
-    ioport_register(&fr->mr->iorange);
 }
 
 static void as_io_range_del(AddressSpace *as, FlatRange *fr)
 {
-    isa_unassign_ioport(int128_get64(fr->addr.start),
-                        int128_get64(fr->addr.size));
 }
 
 static const AddressSpaceOps address_space_ops_io = {
@@ -1456,7 +1433,6 @@ void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
 
 void memory_global_dirty_log_start(void)
 {
-    cpu_physical_memory_set_dirty_tracking(1);
     global_dirty_log = true;
     MEMORY_LISTENER_CALL(log_global_start, Forward);
 }
@@ -1465,7 +1441,6 @@ void memory_global_dirty_log_stop(void)
 {
     global_dirty_log = false;
     MEMORY_LISTENER_CALL(log_global_stop, Reverse);
-    cpu_physical_memory_set_dirty_tracking(0);
 }
 
 static void listener_add_address_space(MemoryListener *listener,
-- 
1.7.9

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

* [Qemu-devel] [PATCH 10/10] memory: drop AddressSpaceOps
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (8 preceding siblings ...)
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 09/10] memory: use a MemoryListener for core memory map updates too Avi Kivity
@ 2012-02-08 15:27 ` Avi Kivity
  2012-02-08 15:35 ` [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
  2012-02-08 23:28 ` Richard Henderson
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:27 UTC (permalink / raw)
  To: qemu-devel

All functionality has been moved to various MemoryListeners.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   56 ++------------------------------------------------------
 1 files changed, 2 insertions(+), 54 deletions(-)

diff --git a/memory.c b/memory.c
index 4e7a90b..4f854d4 100644
--- a/memory.c
+++ b/memory.c
@@ -191,20 +191,12 @@ struct FlatView {
 
 /* A system address space - I/O, memory, etc. */
 struct AddressSpace {
-    const AddressSpaceOps *ops;
     MemoryRegion *root;
     FlatView current_map;
     int ioeventfd_nb;
     MemoryRegionIoeventfd *ioeventfds;
 };
 
-struct AddressSpaceOps {
-    void (*range_add)(AddressSpace *as, FlatRange *fr);
-    void (*range_del)(AddressSpace *as, FlatRange *fr);
-    void (*log_start)(AddressSpace *as, FlatRange *fr);
-    void (*log_stop)(AddressSpace *as, FlatRange *fr);
-};
-
 #define FOR_EACH_FLAT_RANGE(var, view)          \
     for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
 
@@ -336,32 +328,7 @@ static void access_with_adjusted_size(target_phys_addr_t addr,
     }
 }
 
-static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
-{
-}
-
-static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
-{
-}
-
-static void as_memory_log_start(AddressSpace *as, FlatRange *fr)
-{
-}
-
-static void as_memory_log_stop(AddressSpace *as, FlatRange *fr)
-{
-}
-
-static const AddressSpaceOps address_space_ops_memory = {
-    .range_add = as_memory_range_add,
-    .range_del = as_memory_range_del,
-    .log_start = as_memory_log_start,
-    .log_stop = as_memory_log_stop,
-};
-
-static AddressSpace address_space_memory = {
-    .ops = &address_space_ops_memory,
-};
+static AddressSpace address_space_memory;
 
 static const MemoryRegionPortio *find_portio(MemoryRegion *mr, uint64_t offset,
                                              unsigned width, bool write)
@@ -437,22 +404,7 @@ static void memory_region_iorange_write(IORange *iorange,
     .write = memory_region_iorange_write,
 };
 
-static void as_io_range_add(AddressSpace *as, FlatRange *fr)
-{
-}
-
-static void as_io_range_del(AddressSpace *as, FlatRange *fr)
-{
-}
-
-static const AddressSpaceOps address_space_ops_io = {
-    .range_add = as_io_range_add,
-    .range_del = as_io_range_del,
-};
-
-static AddressSpace address_space_io = {
-    .ops = &address_space_ops_io,
-};
+static AddressSpace address_space_io;
 
 static AddressSpace *memory_region_to_address_space(MemoryRegion *mr)
 {
@@ -685,7 +637,6 @@ static void address_space_update_topology_pass(AddressSpace *as,
 
             if (!adding) {
                 MEMORY_LISTENER_UPDATE_REGION(frold, as, Reverse, region_del);
-                as->ops->range_del(as, frold);
             }
 
             ++iold;
@@ -695,9 +646,7 @@ static void address_space_update_topology_pass(AddressSpace *as,
             if (adding) {
                 if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
                     MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse, log_stop);
-                    as->ops->log_stop(as, frnew);
                 } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
-                    as->ops->log_start(as, frnew);
                     MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start);
                 }
             }
@@ -708,7 +657,6 @@ static void address_space_update_topology_pass(AddressSpace *as,
             /* In new */
 
             if (adding) {
-                as->ops->range_add(as, frnew);
                 MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_add);
             }
 
-- 
1.7.9

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

* Re: [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (9 preceding siblings ...)
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 10/10] memory: drop AddressSpaceOps Avi Kivity
@ 2012-02-08 15:35 ` Avi Kivity
  2012-02-08 23:28 ` Richard Henderson
  11 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-08 15:35 UTC (permalink / raw)
  To: qemu-devel

On 02/08/2012 05:27 PM, Avi Kivity wrote:
> This patchset makes the memory core (memory.c) talk to the backend (in exec.c)
> via a MemoryListener instead of named functions.
>
> While the motivation for this is to simplify the memory core, it also enables
> optimizing accelerators some more (by having a tcg MemoryListener to do tcg
> specific core) and allows unit testing of memory.c (by adding a testing
> MemoryListener and seeing what it outputs as various inputs are fed into the
> core).
>

Something that is very visible here is that MemoryListeners switch quite
a lot on the address space.  This suggests that we need to allow
observing a specific address space.  I'll address that in a future patch.

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

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

* Re: [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps
  2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
                   ` (10 preceding siblings ...)
  2012-02-08 15:35 ` [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
@ 2012-02-08 23:28 ` Richard Henderson
  11 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2012-02-08 23:28 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel

On 02/08/2012 07:27 AM, Avi Kivity wrote:
> This patchset makes the memory core (memory.c) talk to the backend (in exec.c)
> via a MemoryListener instead of named functions.
> 
> While the motivation for this is to simplify the memory core, it also enables
> optimizing accelerators some more (by having a tcg MemoryListener to do tcg
> specific core) and allows unit testing of memory.c (by adding a testing
> MemoryListener and seeing what it outputs as various inputs are fed into the
> core).
> 
> Avi Kivity (10):
>   ioport: change portio_list not to use memory_region_set_offset()
>   memory: remove memory_region_set_offset()
>   memory: add shorthand for invoking a callback on all listeners
>   memory: switch memory listeners to a QTAILQ
>   memory: code motion: move MEMORY_LISTENER_CALL()
>   memory: move ioeventfd ops to MemoryListener
>   memory: add a readonly attribute to MemoryRegionSection
>   memory: don't pass ->readable attribute to
>     cpu_register_physical_memory_log
>   memory: use a MemoryListener for core memory map updates too
>   memory: drop AddressSpaceOps

Looks good.

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 09/10] memory: use a MemoryListener for core memory map updates too
  2012-02-08 15:27 ` [Qemu-devel] [PATCH 09/10] memory: use a MemoryListener for core memory map updates too Avi Kivity
@ 2012-02-09  7:58   ` Paolo Bonzini
  2012-02-09  9:28     ` Avi Kivity
  0 siblings, 1 reply; 15+ messages in thread
From: Paolo Bonzini @ 2012-02-09  7:58 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel

On 02/08/2012 04:27 PM, Avi Kivity wrote:
> +static void core_log_stop(MemoryListener *listener,
> +                          MemoryRegionSection *section)
> +{
> +}
> +
> +static void core_log_sync(MemoryListener *listener,
> +                          MemoryRegionSection *section)
> +{
> +}
> +

Why not wrapping the calls inside an "if" so that these dummy functions 
need not be there?  Can be done in a follow-up, though.

Paolo

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

* Re: [Qemu-devel] [PATCH 09/10] memory: use a MemoryListener for core memory map updates too
  2012-02-09  7:58   ` Paolo Bonzini
@ 2012-02-09  9:28     ` Avi Kivity
  0 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-02-09  9:28 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 02/09/2012 09:58 AM, Paolo Bonzini wrote:
> On 02/08/2012 04:27 PM, Avi Kivity wrote:
>> +static void core_log_stop(MemoryListener *listener,
>> +                          MemoryRegionSection *section)
>> +{
>> +}
>> +
>> +static void core_log_sync(MemoryListener *listener,
>> +                          MemoryRegionSection *section)
>> +{
>> +}
>> +
>
> Why not wrapping the calls inside an "if" so that these dummy
> functions need not be there?  Can be done in a follow-up, though.

I dislike that style.  We could have memory.c provide default versions
for users to put into their listener structures.

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

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

end of thread, other threads:[~2012-02-09  9:28 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-08 15:27 [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 01/10] ioport: change portio_list not to use memory_region_set_offset() Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 02/10] memory: remove memory_region_set_offset() Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 03/10] memory: add shorthand for invoking a callback on all listeners Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 04/10] memory: switch memory listeners to a QTAILQ Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 05/10] memory: code motion: move MEMORY_LISTENER_CALL() Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 06/10] memory: move ioeventfd ops to MemoryListener Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 07/10] memory: add a readonly attribute to MemoryRegionSection Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 08/10] memory: don't pass ->readable attribute to cpu_register_physical_memory_log Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 09/10] memory: use a MemoryListener for core memory map updates too Avi Kivity
2012-02-09  7:58   ` Paolo Bonzini
2012-02-09  9:28     ` Avi Kivity
2012-02-08 15:27 ` [Qemu-devel] [PATCH 10/10] memory: drop AddressSpaceOps Avi Kivity
2012-02-08 15:35 ` [Qemu-devel] [PATCH 00/10] Remove AddressSpaceOps Avi Kivity
2012-02-08 23:28 ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).