* [PATCH] xen/dt: Skip non-RAM reserved-memory regions in make_memory_node()
@ 2026-10-28 21:17 Kuan-Wei Chiu
2026-10-30 11:04 ` Orzel, Michal
0 siblings, 1 reply; 3+ messages 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] 3+ messages in thread
* Re: [PATCH] xen/dt: Skip non-RAM reserved-memory regions in make_memory_node()
2026-10-28 21:17 [PATCH] xen/dt: Skip non-RAM reserved-memory regions in make_memory_node() Kuan-Wei Chiu
@ 2026-10-30 11:04 ` Orzel, Michal
2026-10-30 21:58 ` Kuan-Wei Chiu
0 siblings, 1 reply; 3+ messages in thread
From: Orzel, Michal @ 2026-10-30 11:04 UTC (permalink / raw)
To: Kuan-Wei Chiu, xen-devel
Cc: sstabellini, julien, bertrand.marquis, marscheng, jserv,
eleanor15x
On 28-Oct-26 22:17, Kuan-Wei Chiu wrote:
> 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.
Hmm, I always thought that /reserved-memory is to exclude regions from memory
described under /memory. That's what Xen assumes too. map_range_to_domain() for
example does not call iomem_permit_access() for such regions because we assume
it's RAM. Can you provide more details of your board e.g. the device tree? Is
there any documentation I could use to confirm that "reserved-memory can also
describe on-chip SRAM or firmware regions outside system RAM"?
~Michal
>
> 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));
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] xen/dt: Skip non-RAM reserved-memory regions in make_memory_node()
2026-10-30 11:04 ` Orzel, Michal
@ 2026-10-30 21:58 ` Kuan-Wei Chiu
0 siblings, 0 replies; 3+ messages in thread
From: Kuan-Wei Chiu @ 2026-10-30 21:58 UTC (permalink / raw)
To: Orzel, Michal
Cc: xen-devel, sstabellini, julien, bertrand.marquis, marscheng,
jserv, eleanor15x
Hi Michal,
On Fri, Oct 30, 2026 at 12:04:58PM +0100, Orzel, Michal wrote:
>
>
> On 28-Oct-26 22:17, Kuan-Wei Chiu wrote:
> > 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.
> Hmm, I always thought that /reserved-memory is to exclude regions from memory
> described under /memory. That's what Xen assumes too. map_range_to_domain() for
> example does not call iomem_permit_access() for such regions because we assume
> it's RAM. Can you provide more details of your board e.g. the device tree? Is
> there any documentation I could use to confirm that "reserved-memory can also
> describe on-chip SRAM or firmware regions outside system RAM"?
>
Hmm, your reply initially made me wonder if this was caused by a
non-compliant downstream device tree on our side, so I checked the
DT spec and upstream Linux.
The devicetree spec does not seem to explicitly mention whether
/reserved-memory regions must fall within the range described by
/memory. From a quick look at early_init_dt_reserve_memory() in Linux,
the comment there also mentions not worrying if a no-map region is not
memory as it will not be mapped.
In upstream Linux device trees, there are cases like
arch/mips/boot/dts/mobileye/eyeq5.dtsi and eyeq5-epm5.dts, where
/memory starts at 0x40000000 and 0x802000000, while /reserved-memory
defines an on-chip sram region nvram@461fe00 with "nvmem-rmem" outside
/memory.
Our board's device tree is not upstream yet, but it follows a similar
pattern where /reserved-memory defines "nvmem-rmem" and dma pool
sub-regions inside on-chip sram outside the dram range described by
/memory.
Regards,
Kuan-Wei
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-30 21:59 UTC | newest]
Thread overview: 3+ messages (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
2026-10-30 11:04 ` Orzel, Michal
2026-10-30 21:58 ` 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.