diff mbox series

[RFC,1/1] memory: Address space map listener

Message ID 20230405125756.63290-2-quic_acaggian@quicinc.com
State New
Headers show
Series MemoryListener address_space_map callback | expand

Commit Message

Antonio Caggiano April 5, 2023, 12:57 p.m. UTC
Introduce a MemoryListener callback for address space map events.

This will require a change to the memory listener callbacks: while it
currently uses "self" as first argument for the callbacks, this new
approach is going to use an "opaque" member, effectively following the
model used for MemoryRegion and MemoryRegionOps.

Signed-off-by: Antonio Caggiano <quic_acaggian@quicinc.com>
---
 include/exec/memory.h | 19 +++++++++++++++++++
 softmmu/physmem.c     | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

Comments

David Hildenbrand April 5, 2023, 1:23 p.m. UTC | #1
On 05.04.23 14:57, Antonio Caggiano wrote:
> Introduce a MemoryListener callback for address space map events.
> 

Why?
Antonio Caggiano April 5, 2023, 2:25 p.m. UTC | #2
Hi David,

On 05/04/23 15:23, David Hildenbrand wrote:
> On 05.04.23 14:57, Antonio Caggiano wrote:
>> Introduce a MemoryListener callback for address space map events.
>>
> 
> Why?
> 

Please, have a look at the cover letter "[PATCH RFC 0/1] MemoryListener 
address_space_map callback" with a detail explanation of the issue and 
the reason behind this. While I think it solves the issue for my use 
case, it might not be the best or even the right solution for it.

Cheers,
Antonio
David Hildenbrand April 5, 2023, 2:26 p.m. UTC | #3
On 05.04.23 16:25, Antonio Caggiano wrote:
> Hi David,
> 
> On 05/04/23 15:23, David Hildenbrand wrote:
>> On 05.04.23 14:57, Antonio Caggiano wrote:
>>> Introduce a MemoryListener callback for address space map events.
>>>
>>
>> Why?
>>
> 
> Please, have a look at the cover letter "[PATCH RFC 0/1] MemoryListener
> address_space_map callback" with a detail explanation of the issue and
> the reason behind this. While I think it solves the issue for my use
> case, it might not be the best or even the right solution for it.

Oh, you did not CC me on the cover letter, so I missed it ...
diff mbox series

Patch

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 7ec6df3289..f959d53a12 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1045,6 +1045,18 @@  struct MemoryListener {
      */
     void (*coalesced_io_del)(MemoryListener *listener, MemoryRegionSection *section,
                                hwaddr addr, hwaddr len);
+
+    /**
+     * @map:
+     *
+     * Called during an address space map.
+     *
+     * @opaque: User data opaque object
+     * @addr: address within that address space
+     * @len: length of buffer
+     */
+    void (*map)(void *opaque, hwaddr addr, hwaddr len);
+
     /**
      * @priority:
      *
@@ -1054,6 +1066,13 @@  struct MemoryListener {
      */
     unsigned priority;
 
+    /**
+     * @opaque:
+     *
+     * Opaque pointer to user data
+     */
+    void *opaque;
+
     /**
      * @name:
      *
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 9486a1ebdf..0f8bad6b40 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -3246,6 +3246,38 @@  flatview_extend_translation(FlatView *fv, hwaddr addr,
     }
 }
 
+enum ListenerDirection { Forward, Reverse };
+
+/*
+ * This will require a change to the memory listener callbacks:
+ * while it currently uses "self" as first argument for the callbacks, this new
+ * approach is going to use an "opaque" member, effectively following the model
+ * used for MemoryRegion and MemoryRegionOps.
+ */
+#define MEMORY_LISTENER_CALL(_as, _callback, _direction, _args...) \
+    do {                                                                \
+        MemoryListener *_listener;                                      \
+                                                                        \
+        switch (_direction) {                                           \
+        case Forward:                                                   \
+            QTAILQ_FOREACH(_listener, &(_as)->listeners, link_as) {     \
+                if (_listener->_callback) {                             \
+                    _listener->_callback(_listener->opaque, ##_args);   \
+                }                                                       \
+            }                                                           \
+            break;                                                      \
+        case Reverse:                                                   \
+            QTAILQ_FOREACH_REVERSE(_listener, &(_as)->listeners, link_as) { \
+                if (_listener->_callback) {                             \
+                    _listener->_callback(_listener->opaque, ##_args);   \
+                }                                                       \
+            }                                                           \
+            break;                                                      \
+        default:                                                        \
+            abort();                                                    \
+        }                                                               \
+    } while (0)
+
 /* 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.
@@ -3268,6 +3300,8 @@  void *address_space_map(AddressSpace *as,
         return NULL;
     }
 
+    MEMORY_LISTENER_CALL(as, map, Reverse, addr, len);
+
     l = len;
     RCU_READ_LOCK_GUARD();
     fv = address_space_to_flatview(as);