[RFC v2 10/26] memory: Expose FlatView refcount interfaces to Rust

Zhao Liu <[email protected]> Wed, 8 Jul 2026 16:10:36 +0800
Newsgroups org.nongnu.qemu-rust,org.nongnu.qemu-devel
Message-ID <[email protected]>
Move the declarations of the following functions to memory.h so that
Rust can generate bindings for them:
* flatview_ref
* flatview_unref

In addition, add documentation for these two interfaces.

Note that these interfaces serve the address_space_to_flatview()
logic. However, address_space_to_flatview() is not exposed to Rust
because Rust can perform qatomic_rcu_read() itself. Furthermore,
acquiring the RCU lock in Rust while C reads "current_map" via
qatomic_rcu_read() would make for a very dangerous cross-FFI design.

Instead, Rust should either use address_space_get_flatview() directly,
or implement the logic entirely on the Rust side. The latter is a more
worthwhile approach, as the RCU reader pattern (qatomic_rcu_read()
within an RCU critical section) is a general pattern in QEMU.

Signed-off-by: Zhao Liu <[email protected]>
---
Changes since v1:
 * Do not expose address_space_to_flatview() to Rust anymore.
---
 include/system/memory.h  | 34 ++++++++++++++++++++++++++++++++++
 system/memory-internal.h |  1 -
 system/memory.c          |  2 +-
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/include/system/memory.h b/include/system/memory.h
index 47a0e06fbf8a..bf5bfa7164fb 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -948,6 +948,40 @@ static inline FlatView *address_space_to_flatview(const AddressSpace *as)
     return qatomic_rcu_read(&as->current_map);
 }
 
+/**
+ * flatview_ref: Atomically increment the reference count of a #FlatView.
+ *
+ * @view: The #FlatView whose reference count is to be incremented.
+ *
+ * This function attempts to atomically increment the reference count
+ * of the given @view. This operation is conditional and will only
+ * succeed if the current reference count is non-zero.
+ *
+ * A non-zero reference count indicates that the #FlatView is live and
+ * in use. If the reference count is already zero, it indicates that the
+ * #FlatView is being deinitialized, and no new references can be
+ * acquired.
+ *
+ * Returns:
+ * true if the reference count was successfully incremented (i.e., it
+ * was non-zero before the call).
+ * false if the reference count was already zero and could not be
+ * incremented.
+ */
+bool flatview_ref(FlatView *view);
+
+/**
+ * flatview_unref: Atomically decrement the reference count of a
+ * #FlatView.
+ *
+ * @view: The #FlatView to be unreferenced.
+ *
+ * This function atomically decrements the reference count of the given
+ * @view. When the reference count drops to zero, the #FlatView will be
+ * destroyed via RCU.
+ */
+void flatview_unref(FlatView *view);
+
 /**
  * typedef flatview_cb: callback for flatview_for_each_range()
  *
diff --git a/system/memory-internal.h b/system/memory-internal.h
index b2b9b5b0c5eb..c9264a239689 100644
--- a/system/memory-internal.h
+++ b/system/memory-internal.h
@@ -28,7 +28,6 @@ AddressSpaceDispatch *address_space_to_dispatch(const AddressSpace *as)
 }
 
 FlatView *address_space_get_flatview(const AddressSpace *as);
-void flatview_unref(FlatView *view);
 
 extern const MemoryRegionOps unassigned_mem_ops;
 
diff --git a/system/memory.c b/system/memory.c
index 5fc36708ec34..a18885dfd423 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -305,7 +305,7 @@ static void flatview_destroy(FlatView *view)
     g_free(view);
 }
 
-static bool flatview_ref(FlatView *view)
+bool flatview_ref(FlatView *view)
 {
     return qatomic_fetch_inc_nonzero(&view->ref) > 0;
 }
-- 
2.34.1