@@ -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:
*
@@ -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);
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(+)