qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 01/20] memory: allow MemoryListeners to observe a sp


From: Avi Kivity
Subject: [Qemu-devel] [PATCH 01/20] memory: allow MemoryListeners to observe a specific address space
Date: Tue, 14 Feb 2012 11:27:31 +0200

Ignore any regions not belonging to a specified address space.

Signed-off-by: Avi Kivity <address@hidden>
---
 exec.c     |    2 +-
 hw/vhost.c |    2 +-
 kvm-all.c  |    2 +-
 memory.c   |   45 +++++++++++++++++++++++++++++++++++++++------
 memory.h   |    4 +++-
 xen-all.c  |    2 +-
 6 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/exec.c b/exec.c
index 7fb5d4e..aa54eb1 100644
--- a/exec.c
+++ b/exec.c
@@ -3571,7 +3571,7 @@ static void memory_map_init(void)
     memory_region_init(system_io, "io", 65536);
     set_system_io_map(system_io);
 
-    memory_listener_register(&core_memory_listener);
+    memory_listener_register(&core_memory_listener, NULL);
 }
 
 MemoryRegion *get_system_memory(void)
diff --git a/hw/vhost.c b/hw/vhost.c
index e1e7e01..01f676a 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -774,7 +774,7 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool 
force)
     hdev->log_size = 0;
     hdev->log_enabled = false;
     hdev->started = false;
-    memory_listener_register(&hdev->memory_listener);
+    memory_listener_register(&hdev->memory_listener, NULL);
     hdev->force = force;
     return 0;
 fail:
diff --git a/kvm-all.c b/kvm-all.c
index a05e591..15bc42f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1049,7 +1049,7 @@ int kvm_init(void)
     }
 
     kvm_state = s;
-    memory_listener_register(&kvm_memory_listener);
+    memory_listener_register(&kvm_memory_listener, NULL);
 
     s->many_ioeventfds = kvm_check_many_ioeventfds();
 
diff --git a/memory.c b/memory.c
index 4f854d4..e66e39a 100644
--- a/memory.c
+++ b/memory.c
@@ -84,7 +84,14 @@ static AddrRange addrrange_intersection(AddrRange r1, 
AddrRange r2)
 
 enum ListenerDirection { Forward, Reverse };
 
-#define MEMORY_LISTENER_CALL(_callback, _direction, _args...)           \
+static bool memory_listener_match(MemoryListener *listener,
+                                  MemoryRegionSection *section)
+{
+    return !listener->address_space_filter
+        || listener->address_space_filter == section->address_space;
+}
+
+#define MEMORY_LISTENER_CALL_GLOBAL(_callback, _direction, _args...)    \
     do {                                                                \
         MemoryListener *_listener;                                      \
                                                                         \
@@ -105,15 +112,40 @@ static AddrRange addrrange_intersection(AddrRange r1, 
AddrRange r2)
         }                                                               \
     } while (0)
 
+#define MEMORY_LISTENER_CALL(_callback, _direction, _section, _args...) \
+    do {                                                                \
+        MemoryListener *_listener;                                      \
+                                                                        \
+        switch (_direction) {                                           \
+        case Forward:                                                   \
+            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
+                if (memory_listener_match(_listener, _section)) {       \
+                    _listener->_callback(_listener, _section, ##_args); \
+                }                                                       \
+            }                                                           \
+            break;                                                      \
+        case Reverse:                                                   \
+            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
+                                   memory_listeners, link) {            \
+                if (memory_listener_match(_listener, _section)) {       \
+                    _listener->_callback(_listener, _section, ##_args); \
+                }                                                       \
+            }                                                           \
+            break;                                                      \
+        default:                                                        \
+            abort();                                                    \
+        }                                                               \
+    } while (0)
+
 #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
-    MEMORY_LISTENER_CALL(callback, dir, &(MemoryRegionSection) {        \
+    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),  \
         .readonly = (fr)->readonly,                                     \
-                })
+              }))
 
 struct CoalescedMemoryRange {
     AddrRange addr;
@@ -1382,13 +1414,13 @@ void memory_global_sync_dirty_bitmap(MemoryRegion 
*address_space)
 void memory_global_dirty_log_start(void)
 {
     global_dirty_log = true;
-    MEMORY_LISTENER_CALL(log_global_start, Forward);
+    MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward);
 }
 
 void memory_global_dirty_log_stop(void)
 {
     global_dirty_log = false;
-    MEMORY_LISTENER_CALL(log_global_stop, Reverse);
+    MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
 }
 
 static void listener_add_address_space(MemoryListener *listener,
@@ -1412,10 +1444,11 @@ static void listener_add_address_space(MemoryListener 
*listener,
     }
 }
 
-void memory_listener_register(MemoryListener *listener)
+void memory_listener_register(MemoryListener *listener, MemoryRegion *filter)
 {
     MemoryListener *other = NULL;
 
+    listener->address_space_filter = filter;
     if (QTAILQ_EMPTY(&memory_listeners)
         || listener->priority >= QTAILQ_LAST(&memory_listeners,
                                              memory_listeners)->priority) {
diff --git a/memory.h b/memory.h
index 1d99cee..bc9600b 100644
--- a/memory.h
+++ b/memory.h
@@ -193,6 +193,7 @@ struct MemoryListener {
                         bool match_data, uint64_t data, int fd);
     /* Lower = earlier (during add), later (during del) */
     unsigned priority;
+    MemoryRegion *address_space_filter;
     QTAILQ_ENTRY(MemoryListener) link;
 };
 
@@ -685,8 +686,9 @@ void memory_region_transaction_commit(void);
  *                           space
  *
  * @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);
+void memory_listener_register(MemoryListener *listener, MemoryRegion *filter);
 
 /**
  * memory_listener_unregister: undo the effect of memory_listener_register()
diff --git a/xen-all.c b/xen-all.c
index e005b63..dd52f02 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -989,7 +989,7 @@ int xen_hvm_init(void)
 
     state->memory_listener = xen_memory_listener;
     QLIST_INIT(&state->physmap);
-    memory_listener_register(&state->memory_listener);
+    memory_listener_register(&state->memory_listener, NULL);
     state->log_for_dirtybit = NULL;
 
     /* Initialize backend core & drivers */
-- 
1.7.9




reply via email to

[Prev in Thread] Current Thread [Next in Thread]