All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xen/dt: Skip non-RAM reserved-memory regions in make_memory_node()
@ 2026-10-28 21:17 Kuan-Wei Chiu
  0 siblings, 0 replies; only message in thread
From: Kuan-Wei Chiu @ 2026-10-28 21:17 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, julien, bertrand.marquis, michal.orzel, marscheng,
	jserv, eleanor15x, Kuan-Wei Chiu

Xen creates a second /memory node for Dom0 from
bootinfo_get_reserved_mem() without checking whether those regions
belong to host RAM. However, /reserved-memory can also describe
on-chip SRAM or firmware regions outside system RAM. Listing them in a
/memory node causes Dom0 to register non-RAM addresses as system RAM,
conflicting with device MMIO mappings.

Skip reserved-memory banks outside the host RAM banks reported by
bootinfo_get_mem() in make_memory_node().

Fixes: 248faa637d2f ("xen/arm: add reserved-memory regions to the dom0 memory node")
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
Found while trying to bring up Xen on new hardware.
Tested on real silicon.

 xen/common/device-tree/domain-build.c | 42 +++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/xen/common/device-tree/domain-build.c b/xen/common/device-tree/domain-build.c
index 30a59abfa7..33baf150a6 100644
--- a/xen/common/device-tree/domain-build.c
+++ b/xen/common/device-tree/domain-build.c
@@ -504,6 +504,34 @@ int __init make_chosen_node(const struct kernel_info *kinfo)
     return res;
 }
 
+static bool __init is_in_host_ram(const struct membank *bank)
+{
+    const struct membanks *ram = bootinfo_get_mem();
+    paddr_t start = bank->start;
+    paddr_t end = start + bank->size;
+    unsigned int i;
+
+    if ( !bank->size || end < start )
+        return false;
+
+    for ( i = 0; i < ram->nr_banks; i++ )
+    {
+        paddr_t ram_start = ram->bank[i].start;
+        paddr_t ram_end = ram_start + ram->bank[i].size;
+
+        if ( start < ram_start )
+            return false;
+
+        if ( end <= ram_end )
+            return true;
+
+        if ( start < ram_end )
+            start = ram_end;
+    }
+
+    return false;
+}
+
 int __init make_memory_node(const struct kernel_info *kinfo, int addrcells,
                             int sizecells, const struct membanks *mem)
 {
@@ -513,14 +541,20 @@ int __init make_memory_node(const struct kernel_info *kinfo, int addrcells,
     int nr_cells = 0;
     __be32 reg[DT_MEM_NODE_REG_RANGE_SIZE];
     __be32 *cells;
+    bool is_resv = (mem == bootinfo_get_reserved_mem());
 
     if ( mem->nr_banks == 0 )
         return -ENOENT;
 
     /* find the first memory range that is reserved for device (or firmware) */
-    for ( i = 0; i < mem->nr_banks &&
-                 (mem->bank[i].type != MEMBANK_DEFAULT); i++ )
-        ;
+    for ( i = 0; i < mem->nr_banks; i++ )
+    {
+        if ( mem->bank[i].type != MEMBANK_DEFAULT )
+            continue;
+        if ( is_resv && !is_in_host_ram(&mem->bank[i]) )
+            continue;
+        break;
+    }
 
     if ( i == mem->nr_banks )
         return 0;
@@ -544,6 +578,8 @@ int __init make_memory_node(const struct kernel_info *kinfo, int addrcells,
         if ( (mem->bank[i].type == MEMBANK_STATIC_DOMAIN) ||
              (mem->bank[i].type == MEMBANK_FDT_RESVMEM) )
             continue;
+        if ( is_resv && !is_in_host_ram(&mem->bank[i]) )
+            continue;
 
         nr_cells += reg_size;
         BUG_ON(nr_cells > ARRAY_SIZE(reg));
-- 
2.56.0.385.gac671c819a-goog



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-28 21:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-28 21:17 [PATCH] xen/dt: Skip non-RAM reserved-memory regions in make_memory_node() Kuan-Wei Chiu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.