public inbox for linux-riscv@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH fixes] riscv: Properly export reserved regions in /proc/iomem
@ 2025-04-09 18:21 Björn Töpel
  2025-04-11 10:28 ` Alexandre Ghiti
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Björn Töpel @ 2025-04-09 18:21 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Alexandre Ghiti, Nick Kossifidis,
	linux-riscv
  Cc: Björn Töpel, linux-kernel

From: Björn Töpel <bjorn@rivosinc.com>

The /proc/iomem represents the kernel's memory map. Regions marked
with "Reserved" tells the user that the range should not be tampered
with. Kexec-tools, when using the older kexec_load syscall relies on
the "Reserved" regions to build the memory segments, that will be the
target of the new kexec'd kernel.

The RISC-V port tries to expose all reserved regions to userland, but
some regions were not properly exposed: Regions that resided in both
the "regular" and reserved memory block, e.g. the EFI Memory Map. A
missing entry could result in reserved memory being overwritten.

It turns out, that arm64, and loongarch had a similar issue a while
back:

  commit d91680e687f4 ("arm64: Fix /proc/iomem for reserved but not memory regions")
  commit 50d7ba36b916 ("arm64: export memblock_reserve()d regions via /proc/iomem")

Similar to the other ports, resolve the issue by splitting the regions
in an arch initcall, since we need a working allocator.

Fixes: ffe0e5261268 ("RISC-V: Improve init_resources()")
Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
---
 arch/riscv/kernel/setup.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index c174544eefc8..f7c9a1caa83e 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -66,6 +66,9 @@ static struct resource bss_res = { .name = "Kernel bss", };
 static struct resource elfcorehdr_res = { .name = "ELF Core hdr", };
 #endif
 
+static int num_standard_resources;
+static struct resource *standard_resources;
+
 static int __init add_resource(struct resource *parent,
 				struct resource *res)
 {
@@ -139,7 +142,7 @@ static void __init init_resources(void)
 	struct resource *res = NULL;
 	struct resource *mem_res = NULL;
 	size_t mem_res_sz = 0;
-	int num_resources = 0, res_idx = 0;
+	int num_resources = 0, res_idx = 0, non_resv_res = 0;
 	int ret = 0;
 
 	/* + 1 as memblock_alloc() might increase memblock.reserved.cnt */
@@ -193,6 +196,7 @@ static void __init init_resources(void)
 	/* Add /memory regions to the resource tree */
 	for_each_mem_region(region) {
 		res = &mem_res[res_idx--];
+		non_resv_res++;
 
 		if (unlikely(memblock_is_nomap(region))) {
 			res->name = "Reserved";
@@ -210,6 +214,9 @@ static void __init init_resources(void)
 			goto error;
 	}
 
+	num_standard_resources = non_resv_res;
+	standard_resources = &mem_res[res_idx + 1];
+
 	/* Clean-up any unused pre-allocated resources */
 	if (res_idx >= 0)
 		memblock_free(mem_res, (res_idx + 1) * sizeof(*mem_res));
@@ -221,6 +228,33 @@ static void __init init_resources(void)
 	memblock_free(mem_res, mem_res_sz);
 }
 
+static int __init reserve_memblock_reserved_regions(void)
+{
+	u64 i, j;
+
+	for (i = 0; i < num_standard_resources; i++) {
+		struct resource *mem = &standard_resources[i];
+		phys_addr_t r_start, r_end, mem_size = resource_size(mem);
+
+		if (!memblock_is_region_reserved(mem->start, mem_size))
+			continue;
+
+		for_each_reserved_mem_range(j, &r_start, &r_end) {
+			resource_size_t start, end;
+
+			start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start);
+			end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end);
+
+			if (start > mem->end || end < mem->start)
+				continue;
+
+			reserve_region_with_split(mem, start, end, "Reserved");
+		}
+	}
+
+	return 0;
+}
+arch_initcall(reserve_memblock_reserved_regions);
 
 static void __init parse_dtb(void)
 {

base-commit: a24588245776dafc227243a01bfbeb8a59bafba9
-- 
2.45.2


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-07-16 18:16 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-09 18:21 [PATCH fixes] riscv: Properly export reserved regions in /proc/iomem Björn Töpel
2025-04-11 10:28 ` Alexandre Ghiti
2025-04-16 18:42 ` patchwork-bot+linux-riscv
2025-06-30 11:21 ` [PATCH 0/1] Fix for riscv vmcore issue Pnina Feder
2025-06-30 13:33   ` Björn Töpel
2025-07-03 12:06     ` Pnina Feder
2025-07-04 12:25       ` Alexandre Ghiti
2025-07-06 13:57         ` Pnina Feder
2025-07-14 12:00           ` Pnina Feder
2025-07-16  6:58             ` Alexandre Ghiti
2025-07-16 11:05               ` Pnina Feder
2025-07-16 11:47                 ` Alexandre Ghiti
2025-07-16 18:16                   ` Nick Kossifidis
2025-06-30 11:21 ` [PATCH 1/1] riscv: Change memblock reserved name to be recognized on kexec Pnina Feder

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox