Introduce address_space_range_is_ram(), a helper to determine whether a
guest physical address range within an AddressSpace resolves entirely
to RAM-backed MemoryRegions. The range is walked using
address_space_translate() so contiguous RAM-only ranges return true
even when they cross multiple MemoryRegion boundaries; any byte
backed by non-RAM (MMIO, ROM device, hole) returns false.

Signed-off-by: Shameer Kolothum <[email protected]>
---
 include/system/memory.h | 13 +++++++++++++
 system/physmem.c        | 19 +++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/include/system/memory.h b/include/system/memory.h
index 1417132f6d..af5f96f6ff 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -2841,6 +2841,19 @@ bool address_space_access_valid(AddressSpace *as, hwaddr 
addr, hwaddr len,
  */
 bool address_space_is_io(AddressSpace *as, hwaddr addr);
 
+/**
+ * address_space_range_is_ram: check whether a guest physical address range
+ *                             within an address space resolves entirely to 
RAM.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @size: number of bytes in the range starting at @addr
+ *
+ * Returns true if every byte in [@addr, @addr + @size) maps to a RAM
+ * MemoryRegion, false otherwise.
+ */
+bool address_space_range_is_ram(AddressSpace *as, hwaddr addr, hwaddr size);
+
 /* address_space_map: map a physical memory region into a host virtual address
  *
  * May map a subset of the requested range, given by and returned in @plen.
diff --git a/system/physmem.c b/system/physmem.c
index 7bcbf87573..46b36c7b10 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -3668,6 +3668,25 @@ bool address_space_is_io(AddressSpace *as, hwaddr addr)
     return !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
 }
 
+bool address_space_range_is_ram(AddressSpace *as, hwaddr addr, hwaddr size)
+{
+    MemoryRegion *mr;
+    hwaddr xlat, l;
+
+    RCU_READ_LOCK_GUARD();
+    while (size > 0) {
+        l = size;
+        mr = address_space_translate(as, addr, &xlat, &l, false,
+                                     MEMTXATTRS_UNSPECIFIED);
+        if (!memory_region_is_ram(mr)) {
+            return false;
+        }
+        size -= l;
+        addr += l;
+    }
+    return true;
+}
+
 static hwaddr
 flatview_extend_translation(FlatView *fv, hwaddr addr,
                             hwaddr target_len,
-- 
2.43.0


Reply via email to