Devicetree
 help / color / mirror / Atom feed
* [PATCH v3 00/11] kdump: reduce vmcore size and capture time
@ 2026-05-27  3:29 Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 01/11] of: reserved_mem: handle NULL name in of_reserved_mem_lookup() Wandun Chen
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

On SoCs that carve out large firmware-owned reserved memory (GPU
firmware, DSP, modem, camera ISP, NPU, ...), kdump currently dumps
those carveouts as part of system RAM even though their contents are
firmware state that is not useful for kernel crash analysis.

This series introduces an opt-in 'dumpable' flag [1] on struct
reserved_mem and uses it to filter the elfcorehdr PT_LOAD ranges on
DT-based architectures (arm64, riscv, loongarch). By default reserved
regions are treated as non-dumpable; CMA regions are explicitly opted
in because their pages are returned to the buddy allocator and may
carry key crash-analysis data.

The series is organized as follows:
Patches 1-3: Pre-existing fixes and a small prep change.
Patches 4-5: Restructure to allow appending /memreserve/ entries.
Patches 6-7: Add a dumpable flag and append /memreserve/ entries.
Patch 8: Add generic kdump helpers.
Patches 9-11: Wire the helpers into arm64, riscv and loongarch kdump
              elfcorehdr preparation.

v2 --> v3:
1. Fix out-of-bounds issue if device tree lacks /reserved-memory node.[2]
2. Fix UAF issue when alloc_reserved_mem_array() fails.
3. Add some prepare patches.

v1 --> v2:
1. v1 added an opt-out DT property ('linux,no-dump'). Per Rob's
   feedback [1], v2 drop that property and exclude reserve memory
   by default.
2. Split some prepared patches from the original patches.
3. Address coding-style comments on patch 5 from Rob.

[1] https://lore.kernel.org/lkml/20260506144542.GA2072596-robh@kernel.org/
[2] https://sashiko.dev/#/patchset/20260520091844.592753-1-chenwandun%40lixiang.com?part=4

Wandun Chen (11):
  of: reserved_mem: handle NULL name in of_reserved_mem_lookup()
  kexec/crash: provide crash_exclude_mem_range() stub when
    CONFIG_CRASH_DUMP=n
  of: reserved_mem: avoid post-init UAF when alloc_reserved_mem_array()
    fails
  of: reserved_mem: zero total_reserved_mem_cnt if no valid
    /reserved-memory entry
  of: reserved_mem: split alloc_reserved_mem_array() from
    fdt_scan_reserved_mem_late()
  of: reserved_mem: add dumpable flag to opt-in vmcore
  of: reserved_mem: save /memreserve/ entries into the reserved_mem
    array
  of: reserved_mem: add kdump helpers to exclude non-dumpable regions
  arm64: kdump: exclude non-dumpable reserved memory regions from vmcore
  riscv: kdump: exclude non-dumpable reserved memory regions from vmcore
  loongarch: kdump: exclude non-dumpable reserved memory regions from
    vmcore

 arch/arm64/kernel/machine_kexec_file.c     |   6 ++
 arch/loongarch/kernel/machine_kexec_file.c |   6 ++
 arch/riscv/kernel/machine_kexec_file.c     |   4 +
 drivers/of/fdt.c                           |  11 +-
 drivers/of/of_private.h                    |   3 +
 drivers/of/of_reserved_mem.c               | 117 +++++++++++++++++++--
 include/linux/crash_core.h                 |   6 ++
 include/linux/of_reserved_mem.h            |  15 +++
 kernel/dma/contiguous.c                    |   1 +
 9 files changed, 157 insertions(+), 12 deletions(-)

-- 
2.43.0


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

* [PATCH v3 01/11] of: reserved_mem: handle NULL name in of_reserved_mem_lookup()
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 02/11] kexec/crash: provide crash_exclude_mem_range() stub when CONFIG_CRASH_DUMP=n Wandun Chen
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Prepare for an upcoming change that appends /memreserve/ entries to
reserved_mem[]; such entries have no name.

No functional change.

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
---
 drivers/of/of_reserved_mem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 8d5777cb5d1b..313cbc57aa45 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -788,7 +788,8 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np)
 
 	name = kbasename(np->full_name);
 	for (i = 0; i < reserved_mem_count; i++)
-		if (!strcmp(reserved_mem[i].name, name))
+		if (reserved_mem[i].name &&
+		    !strcmp(reserved_mem[i].name, name))
 			return &reserved_mem[i];
 
 	return NULL;
-- 
2.43.0


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

* [PATCH v3 02/11] kexec/crash: provide crash_exclude_mem_range() stub when CONFIG_CRASH_DUMP=n
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 01/11] of: reserved_mem: handle NULL name in of_reserved_mem_lookup() Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 03/11] of: reserved_mem: avoid post-init UAF when alloc_reserved_mem_array() fails Wandun Chen
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Prepare for an upcoming change that excludes non-dumpable reserved
regions from the kdump vmcore and will call crash_exclude_mem_range()
from generic, non-arch code.

No functional change.

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
---
 include/linux/crash_core.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index c1dee3f971a9..0033d4777648 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -87,6 +87,12 @@ static inline int kexec_should_crash(struct task_struct *p) { return 0; }
 static inline int kexec_crash_loaded(void) { return 0; }
 static inline void crash_save_cpu(struct pt_regs *regs, int cpu) {};
 static inline int kimage_crash_copy_vmcoreinfo(struct kimage *image) { return 0; };
+static inline int crash_exclude_mem_range(struct crash_mem *mem,
+					  unsigned long long mstart,
+					  unsigned long long mend)
+{
+	return 0;
+}
 #endif /* CONFIG_CRASH_DUMP*/
 
 #ifdef CONFIG_CRASH_DM_CRYPT
-- 
2.43.0


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

* [PATCH v3 03/11] of: reserved_mem: avoid post-init UAF when alloc_reserved_mem_array() fails
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 01/11] of: reserved_mem: handle NULL name in of_reserved_mem_lookup() Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 02/11] kexec/crash: provide crash_exclude_mem_range() stub when CONFIG_CRASH_DUMP=n Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 04/11] of: reserved_mem: zero total_reserved_mem_cnt if no valid /reserved-memory entry Wandun Chen
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

The global pointer 'reserved_mem' continues to reference the
reserved_mem_array which lives in __initdata if
alloc_reserved_mem_array() fails. of_reserved_mem_lookup() is
exported for post-init use, that would dereference freed memory
and trigger a use-after-free.

So reset reserved_mem_count to 0 when alloc_reserved_mem_array()
fails.

Fixes: 00c9a452a235 ("of: reserved_mem: Add code to dynamically allocate reserved_mem array")
Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
---
 drivers/of/of_reserved_mem.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 313cbc57aa45..6d479381ff1f 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -69,29 +69,31 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
  * the initial static array is copied over to this new array and
  * the new array is used from this point on.
  */
-static void __init alloc_reserved_mem_array(void)
+static bool __init alloc_reserved_mem_array(void)
 {
 	struct reserved_mem *new_array;
 	size_t alloc_size, copy_size, memset_size;
 
+	if (!total_reserved_mem_cnt)
+		return true;
+
 	alloc_size = array_size(total_reserved_mem_cnt, sizeof(*new_array));
 	if (alloc_size == SIZE_MAX) {
 		pr_err("Failed to allocate memory for reserved_mem array with err: %d", -EOVERFLOW);
-		return;
+		goto fail;
 	}
 
 	new_array = memblock_alloc(alloc_size, SMP_CACHE_BYTES);
 	if (!new_array) {
 		pr_err("Failed to allocate memory for reserved_mem array with err: %d", -ENOMEM);
-		return;
+		goto fail;
 	}
 
 	copy_size = array_size(reserved_mem_count, sizeof(*new_array));
 	if (copy_size == SIZE_MAX) {
 		memblock_free(new_array, alloc_size);
-		total_reserved_mem_cnt = MAX_RESERVED_REGIONS;
 		pr_err("Failed to allocate memory for reserved_mem array with err: %d", -EOVERFLOW);
-		return;
+		goto fail;
 	}
 
 	memset_size = alloc_size - copy_size;
@@ -100,6 +102,11 @@ static void __init alloc_reserved_mem_array(void)
 	memset(new_array + reserved_mem_count, 0, memset_size);
 
 	reserved_mem = new_array;
+	return true;
+
+fail:
+	reserved_mem_count = 0;
+	return false;
 }
 
 static void fdt_init_reserved_mem_node(unsigned long node, const char *uname,
@@ -266,7 +273,8 @@ void __init fdt_scan_reserved_mem_late(void)
 	}
 
 	/* Attempt dynamic allocation of a new reserved_mem array */
-	alloc_reserved_mem_array();
+	if (!alloc_reserved_mem_array())
+		return;
 
 	if (__reserved_mem_check_root(node)) {
 		pr_err("Reserved memory: unsupported node format, ignoring\n");
-- 
2.43.0


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

* [PATCH v3 04/11] of: reserved_mem: zero total_reserved_mem_cnt if no valid /reserved-memory entry
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
                   ` (2 preceding siblings ...)
  2026-05-27  3:29 ` [PATCH v3 03/11] of: reserved_mem: avoid post-init UAF when alloc_reserved_mem_array() fails Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  3:53   ` sashiko-bot
  2026-05-27  3:29 ` [PATCH v3 05/11] of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late() Wandun Chen
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Prepare for storing /memreserve/ entries in the reserved_mem array.
Zero total_reserved_mem_cnt if no valid /reserved-memory entry,
instead of keeping it's initial value of MAX_RESERVED_REGIONS, this
allows accounting /memreserve entries based on total_reserved_mem_cnt
in a follow-up patch.

No functional change.

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
---
 drivers/of/of_reserved_mem.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 6d479381ff1f..05defc91e901 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -329,11 +329,14 @@ int __init fdt_scan_reserved_mem(void)
 	const void *fdt = initial_boot_params;
 
 	node = fdt_path_offset(fdt, "/reserved-memory");
-	if (node < 0)
+	if (node < 0) {
+		total_reserved_mem_cnt = 0;
 		return -ENODEV;
+	}
 
 	if (__reserved_mem_check_root(node) != 0) {
 		pr_err("Reserved memory: unsupported node format, ignoring\n");
+		total_reserved_mem_cnt = 0;
 		return -EINVAL;
 	}
 
-- 
2.43.0


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

* [PATCH v3 05/11] of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late()
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
                   ` (3 preceding siblings ...)
  2026-05-27  3:29 ` [PATCH v3 04/11] of: reserved_mem: zero total_reserved_mem_cnt if no valid /reserved-memory entry Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  4:21   ` sashiko-bot
  2026-05-27  3:29 ` [PATCH v3 06/11] of: reserved_mem: add dumpable flag to opt-in vmcore Wandun Chen
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Prepare for storing /memreserve/ entries in the reserved_mem array.
alloc_reserved_mem_array is skipped if the device tree lacks a
/reserved-memory node, pointer 'reserved_mem' continues to reference
the reserved_mem_array which lives in __initdata, storing
/memreserve/ entries into reserved_mem_array would result in metadata
loss, and an out-of-bounds memory access will occur if the device
tree contains more than MAX_RESERVED_REGIONS /memreserve/ entries.

So split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late(),
and call alloc_reserved_mem_array() whether or not there is a
/reserved-memory node.

No functional change.
The actual /memreserve/ population is added in a follow-up patch.

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
---
 drivers/of/fdt.c             | 7 +++++--
 drivers/of/of_private.h      | 1 +
 drivers/of/of_reserved_mem.c | 6 +-----
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 82f7327c59ea..83a2a474831e 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1284,8 +1284,11 @@ void __init unflatten_device_tree(void)
 {
 	void *fdt = initial_boot_params;
 
-	/* Save the statically-placed regions in the reserved_mem array */
-	fdt_scan_reserved_mem_late();
+	/* Attempt dynamic allocation of a new reserved_mem array */
+	if (fdt && alloc_reserved_mem_array()) {
+		/* Save the statically-placed regions in the reserved_mem array */
+		fdt_scan_reserved_mem_late();
+	}
 
 	/* Populate an empty root node when bootloader doesn't provide one */
 	if (!fdt) {
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 0ae16da066e2..50e5a533e059 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -187,6 +187,7 @@ static inline struct device_node *__of_get_dma_parent(const struct device_node *
 
 int fdt_scan_reserved_mem(void);
 void __init fdt_scan_reserved_mem_late(void);
+bool __init alloc_reserved_mem_array(void);
 
 bool of_fdt_device_is_available(const void *blob, unsigned long node);
 
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 05defc91e901..888dcb6bdce5 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -69,7 +69,7 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
  * the initial static array is copied over to this new array and
  * the new array is used from this point on.
  */
-static bool __init alloc_reserved_mem_array(void)
+bool __init alloc_reserved_mem_array(void)
 {
 	struct reserved_mem *new_array;
 	size_t alloc_size, copy_size, memset_size;
@@ -272,10 +272,6 @@ void __init fdt_scan_reserved_mem_late(void)
 		return;
 	}
 
-	/* Attempt dynamic allocation of a new reserved_mem array */
-	if (!alloc_reserved_mem_array())
-		return;
-
 	if (__reserved_mem_check_root(node)) {
 		pr_err("Reserved memory: unsupported node format, ignoring\n");
 		return;
-- 
2.43.0


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

* [PATCH v3 06/11] of: reserved_mem: add dumpable flag to opt-in vmcore
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
                   ` (4 preceding siblings ...)
  2026-05-27  3:29 ` [PATCH v3 05/11] of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late() Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 07/11] of: reserved_mem: save /memreserve/ entries into the reserved_mem array Wandun Chen
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Add a 'dumpable' flag to struct reserved_mem so the kernel can decide
whether a reserved area should be included in the kdump vmcore. Most
reserved regions are owned by devices and do not contain data useful
for kernel crash analysis, so excluding them by default is the right
behaviour.

Reusable CMA regions are different: pages in a CMA region are handed
back to the buddy allocator and may contain key data for crash
analysis, so set dumpable to true in rmem_cma_setup().

Suggested-by: Rob Herring <robh@kernel.org>
Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
Tested-by: Meijing Zhao <zhaomeijing@lixiang.com>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/all/20260506144542.GA2072596-robh@kernel.org/
---
 include/linux/of_reserved_mem.h | 1 +
 kernel/dma/contiguous.c         | 1 +
 2 files changed, 2 insertions(+)

diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index e8b20b29fa68..55a67cee41ea 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -15,6 +15,7 @@ struct reserved_mem {
 	phys_addr_t			base;
 	phys_addr_t			size;
 	void				*priv;
+	bool				dumpable;
 };
 
 struct reserved_mem_ops {
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index 03f52bd17120..eddec89eb414 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -579,6 +579,7 @@ static int __init rmem_cma_setup(unsigned long node, struct reserved_mem *rmem)
 		dma_contiguous_default_area = cma;
 
 	rmem->priv = cma;
+	rmem->dumpable = true;
 
 	pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n",
 		&rmem->base, (unsigned long)rmem->size / SZ_1M);
-- 
2.43.0


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

* [PATCH v3 07/11] of: reserved_mem: save /memreserve/ entries into the reserved_mem array
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
                   ` (5 preceding siblings ...)
  2026-05-27  3:29 ` [PATCH v3 06/11] of: reserved_mem: add dumpable flag to opt-in vmcore Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 08/11] of: reserved_mem: add kdump helpers to exclude non-dumpable regions Wandun Chen
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

/memreserve/ is used by firmware or bootloaders, such regions hold no
useful data for crash analysis, they should be excluded from the
kdump vmcore, so save /memreserve/ entries into the reserved_mem array
for later exclusion.

If a /memreserve/ entry overlaps any dumpable reserved region, mark
the whole memreserve entry dumpable as well. This may keep slightly
more memory in vmcore than strictly necessary, but avoids splitting
entries and never drops data that may be useful for crash analysis.

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
Tested-by: Meijing Zhao <zhaomeijing@lixiang.com>
---
 drivers/of/fdt.c             |  4 +++
 drivers/of/of_private.h      |  2 ++
 drivers/of/of_reserved_mem.c | 55 ++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 83a2a474831e..745e53b1c564 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -499,6 +499,7 @@ void __init early_init_fdt_scan_reserved_mem(void)
 	int n;
 	int res;
 	u64 base, size;
+	int nr_memreserve = 0;
 
 	if (!initial_boot_params)
 		return;
@@ -516,7 +517,9 @@ void __init early_init_fdt_scan_reserved_mem(void)
 		if (!size)
 			break;
 		memblock_reserve(base, size);
+		nr_memreserve++;
 	}
+	fdt_reserved_mem_account_memreserve(nr_memreserve);
 }
 
 /**
@@ -1288,6 +1291,7 @@ void __init unflatten_device_tree(void)
 	if (fdt && alloc_reserved_mem_array()) {
 		/* Save the statically-placed regions in the reserved_mem array */
 		fdt_scan_reserved_mem_late();
+		fdt_reserved_mem_save_memreserve_entries();
 	}
 
 	/* Populate an empty root node when bootloader doesn't provide one */
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 50e5a533e059..30954e859689 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -188,6 +188,8 @@ static inline struct device_node *__of_get_dma_parent(const struct device_node *
 int fdt_scan_reserved_mem(void);
 void __init fdt_scan_reserved_mem_late(void);
 bool __init alloc_reserved_mem_array(void);
+void __init fdt_reserved_mem_account_memreserve(int n);
+void __init fdt_reserved_mem_save_memreserve_entries(void);
 
 bool of_fdt_device_is_available(const void *blob, unsigned long node);
 
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 888dcb6bdce5..5e27f9403786 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -248,6 +248,43 @@ static void __init __rmem_check_for_overlap(void)
 	}
 }
 
+static void __init fdt_reserved_mem_add_memreserve(phys_addr_t base,
+						   phys_addr_t size)
+{
+	struct reserved_mem *rmem;
+	bool dumpable = false;
+	int i;
+
+	if (reserved_mem_count == total_reserved_mem_cnt) {
+		pr_err("not enough space for memreserve regions.\n");
+		return;
+	}
+
+	for (i = 0; i < reserved_mem_count; i++) {
+		rmem = &reserved_mem[i];
+
+		if (!rmem->dumpable)
+			continue;
+
+		if (base < rmem->base + rmem->size && rmem->base < base + size) {
+			dumpable = true;
+			break;
+		}
+	}
+
+	rmem = &reserved_mem[reserved_mem_count];
+	rmem->base = base;
+	rmem->size = size;
+	rmem->dumpable = dumpable;
+
+	reserved_mem_count++;
+}
+
+void __init fdt_reserved_mem_account_memreserve(int n)
+{
+	total_reserved_mem_cnt += n;
+}
+
 /**
  * fdt_scan_reserved_mem_late() - Scan FDT and initialize remaining reserved
  * memory regions.
@@ -305,6 +342,24 @@ void __init fdt_scan_reserved_mem_late(void)
 	__rmem_check_for_overlap();
 }
 
+void __init fdt_reserved_mem_save_memreserve_entries(void)
+{
+	const void *fdt = initial_boot_params;
+	u64 base, size;
+	int n;
+
+	if (!fdt)
+		return;
+
+	for (n = 0; ; n++) {
+		if (fdt_get_mem_rsv(fdt, n, &base, &size))
+			break;
+		if (!size)
+			break;
+		fdt_reserved_mem_add_memreserve(base, size);
+	}
+}
+
 static int __init __reserved_mem_alloc_size(unsigned long node, const char *uname);
 
 /*
-- 
2.43.0


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

* [PATCH v3 08/11] of: reserved_mem: add kdump helpers to exclude non-dumpable regions
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
                   ` (6 preceding siblings ...)
  2026-05-27  3:29 ` [PATCH v3 07/11] of: reserved_mem: save /memreserve/ entries into the reserved_mem array Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 09/11] arm64: kdump: exclude non-dumpable reserved memory regions from vmcore Wandun Chen
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Add two helpers to exclude non-dumpable regions for arch-specific
code.

 - of_reserved_mem_kdump_nr_ranges() returns the count of regions
   that are not dumpable. Each excluded region may split an existing
   crash_mem range into two, so callers use this to calculate
   crash_mem allocation size.

 - of_reserved_mem_kdump_exclude() walks reserved_mem[] and calls
   crash_exclude_mem_range() for every non-dumpable region.

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
Tested-by: Meijing Zhao <zhaomeijing@lixiang.com>
---
 drivers/of/of_reserved_mem.c    | 34 +++++++++++++++++++++++++++++++++
 include/linux/of_reserved_mem.h | 14 ++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 5e27f9403786..1d9aa332325b 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/memblock.h>
 #include <linux/kmemleak.h>
+#include <linux/crash_core.h>
 
 #include "of_private.h"
 
@@ -858,6 +859,39 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_reserved_mem_lookup);
 
+/*
+ * Count non-dumpable reserved regions. Excluding each one may split a
+ * crash_mem range in two, callers use this to size the allocation.
+ */
+unsigned int of_reserved_mem_kdump_nr_ranges(void)
+{
+	unsigned int i, n = 0;
+
+	for (i = 0; i < reserved_mem_count; i++)
+		if (reserved_mem[i].size && !reserved_mem[i].dumpable)
+			n++;
+	return n;
+}
+
+/* Exclude non-dumpable reserved regions from @cmem. */
+int of_reserved_mem_kdump_exclude(struct crash_mem *cmem)
+{
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < reserved_mem_count; i++) {
+		struct reserved_mem *r = &reserved_mem[i];
+
+		if (!r->size || r->dumpable)
+			continue;
+		ret = crash_exclude_mem_range(cmem, r->base,
+					      r->base + r->size - 1);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
 /**
  * of_reserved_mem_region_to_resource() - Get a reserved memory region as a resource
  * @np:		node containing 'memory-region' property
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 55a67cee41ea..70db99f1fbff 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -8,6 +8,7 @@
 struct of_phandle_args;
 struct reserved_mem_ops;
 struct resource;
+struct crash_mem;
 
 struct reserved_mem {
 	const char			*name;
@@ -48,6 +49,9 @@ int of_reserved_mem_region_to_resource_byname(const struct device_node *np,
 					      const char *name, struct resource *res);
 int of_reserved_mem_region_count(const struct device_node *np);
 
+unsigned int of_reserved_mem_kdump_nr_ranges(void);
+int of_reserved_mem_kdump_exclude(struct crash_mem *cmem);
+
 #else
 
 #define RESERVEDMEM_OF_DECLARE(name, compat, ops)			\
@@ -92,6 +96,16 @@ static inline int of_reserved_mem_region_count(const struct device_node *np)
 {
 	return 0;
 }
+
+static inline unsigned int of_reserved_mem_kdump_nr_ranges(void)
+{
+	return 0;
+}
+
+static inline int of_reserved_mem_kdump_exclude(struct crash_mem *cmem)
+{
+	return 0;
+}
 #endif
 
 /**
-- 
2.43.0


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

* [PATCH v3 09/11] arm64: kdump: exclude non-dumpable reserved memory regions from vmcore
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
                   ` (7 preceding siblings ...)
  2026-05-27  3:29 ` [PATCH v3 08/11] of: reserved_mem: add kdump helpers to exclude non-dumpable regions Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 10/11] riscv: " Wandun Chen
  2026-05-27  3:29 ` [PATCH v3 11/11] loongarch: " Wandun Chen
  10 siblings, 0 replies; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Reserved memory regions are excluded from vmcore by default unless
marked dumpable. Honor the dumpable flag to filter out device firmware
regions (e.g., GPU, DSP, modem) reserved via device tree, since they
typically contain data not useful for kernel crash analysis and can
significantly increase vmcore size.

Use of_reserved_mem_kdump_exclude() to perform the exclusion, and
pre-size the crash_mem array via of_reserved_mem_kdump_nr_ranges().

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
Tested-by: Meijing Zhao <zhaomeijing@lixiang.com>
---
 arch/arm64/kernel/machine_kexec_file.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index e31fabed378a..1d65320c6ba4 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -17,6 +17,7 @@
 #include <linux/memblock.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
@@ -51,6 +52,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
 	nr_ranges = 2; /* for exclusion of crashkernel region */
 	for_each_mem_range(i, &start, &end)
 		nr_ranges++;
+	nr_ranges += of_reserved_mem_kdump_nr_ranges();
 
 	cmem = kmalloc_flex(*cmem, ranges, nr_ranges);
 	if (!cmem)
@@ -75,6 +77,10 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
 			goto out;
 	}
 
+	ret = of_reserved_mem_kdump_exclude(cmem);
+	if (ret)
+		goto out;
+
 	ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
 
 out:
-- 
2.43.0


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

* [PATCH v3 10/11] riscv: kdump: exclude non-dumpable reserved memory regions from vmcore
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
                   ` (8 preceding siblings ...)
  2026-05-27  3:29 ` [PATCH v3 09/11] arm64: kdump: exclude non-dumpable reserved memory regions from vmcore Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  4:05   ` sashiko-bot
  2026-05-27  3:29 ` [PATCH v3 11/11] loongarch: " Wandun Chen
  10 siblings, 1 reply; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Apply the same non-dumpable reserved memory filtering to RISC-V kdump
as was done for arm64. Use of_reserved_mem_kdump_exclude() to drop
flagged regions from the elfcorehdr PT_LOAD segments, and
of_reserved_mem_kdump_nr_ranges() to pre-size the crash_mem array.

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
---
 arch/riscv/kernel/machine_kexec_file.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/riscv/kernel/machine_kexec_file.c b/arch/riscv/kernel/machine_kexec_file.c
index 54e2d9552e93..c359cf714c79 100644
--- a/arch/riscv/kernel/machine_kexec_file.c
+++ b/arch/riscv/kernel/machine_kexec_file.c
@@ -10,6 +10,7 @@
 #include <linux/elf.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/libfdt.h>
 #include <linux/types.h>
 #include <linux/memblock.h>
@@ -63,6 +64,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
 
 	nr_ranges = 1; /* For exclusion of crashkernel region */
 	walk_system_ram_res(0, -1, &nr_ranges, get_nr_ram_ranges_callback);
+	nr_ranges += of_reserved_mem_kdump_nr_ranges();
 
 	cmem = kmalloc_flex(*cmem, ranges, nr_ranges);
 	if (!cmem)
@@ -76,6 +78,8 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
 
 	/* Exclude crashkernel region */
 	ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
+	if (!ret)
+		ret = of_reserved_mem_kdump_exclude(cmem);
 	if (!ret)
 		ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
 
-- 
2.43.0


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

* [PATCH v3 11/11] loongarch: kdump: exclude non-dumpable reserved memory regions from vmcore
  2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
                   ` (9 preceding siblings ...)
  2026-05-27  3:29 ` [PATCH v3 10/11] riscv: " Wandun Chen
@ 2026-05-27  3:29 ` Wandun Chen
  2026-05-27  4:12   ` sashiko-bot
  10 siblings, 1 reply; 16+ messages in thread
From: Wandun Chen @ 2026-05-27  3:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
	devicetree, kexec, iommu, zhaomeijing
  Cc: catalin.marinas, will, chenhuacai, kernel, pjw, palmer, aou, alex,
	robh, saravanak, akpm, bhe, rppt, pasha.tatashin, pratyush,
	ruirui.yang, m.szyprowski, robin.murphy, quic_obabatun

From: Wandun Chen <chenwandun@lixiang.com>

Apply the same non-dumpable reserved memory filtering to LoongArch
kdump as was done for arm64. Use of_reserved_mem_kdump_exclude() to
drop flagged regions from the elfcorehdr PT_LOAD segments, and
of_reserved_mem_kdump_nr_ranges() to pre-size the crash_mem array.

Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
---
 arch/loongarch/kernel/machine_kexec_file.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
index 5584b798ba46..4b918c3d4a28 100644
--- a/arch/loongarch/kernel/machine_kexec_file.c
+++ b/arch/loongarch/kernel/machine_kexec_file.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/kexec.h>
 #include <linux/memblock.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
@@ -67,6 +68,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
 	nr_ranges = 2; /* for exclusion of crashkernel region */
 	for_each_mem_range(i, &start, &end)
 		nr_ranges++;
+	nr_ranges += of_reserved_mem_kdump_nr_ranges();
 
 	cmem = kmalloc_flex(*cmem, ranges, nr_ranges);
 	if (!cmem)
@@ -91,6 +93,10 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
 			goto out;
 	}
 
+	ret = of_reserved_mem_kdump_exclude(cmem);
+	if (ret)
+		goto out;
+
 	ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
 
 out:
-- 
2.43.0


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

* Re: [PATCH v3 04/11] of: reserved_mem: zero total_reserved_mem_cnt if no valid /reserved-memory entry
  2026-05-27  3:29 ` [PATCH v3 04/11] of: reserved_mem: zero total_reserved_mem_cnt if no valid /reserved-memory entry Wandun Chen
@ 2026-05-27  3:53   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-05-27  3:53 UTC (permalink / raw)
  To: Wandun Chen; +Cc: devicetree, conor+dt, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but the `dynamic_nodes` stack array in `fdt_scan_reserved_mem()` has a fixed size of `MAX_RESERVED_REGIONS` and lacks a bounds check when storing dynamically-placed reserved memory regions, leading to a potential stack buffer overflow.
--

commit d26e031d55dfe0dd2c4b24bada22d27eff019795
Author: Wandun Chen <chenwandun@lixiang.com>

of: reserved_mem: zero total_reserved_mem_cnt if no valid /reserved-memory entry

Prepare for storing /memreserve/ entries in the reserved_mem array.
Zero total_reserved_mem_cnt if no valid /reserved-memory entry exists,
instead of keeping its initial value. This allows accounting for
/memreserve entries in follow-up patches.

> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> index 6d479381ff1fd..05defc91e9015 100644
> --- a/drivers/of/of_reserved_mem.c
> +++ b/drivers/of/of_reserved_mem.c
> @@ -329,11 +329,14 @@ int __init fdt_scan_reserved_mem(void)
>  	const void *fdt = initial_boot_params;
>  
>  	node = fdt_path_offset(fdt, "/reserved-memory");
> -	if (node < 0)
> +	if (node < 0) {
> +		total_reserved_mem_cnt = 0;
>  		return -ENODEV;
> +	}
>  
>  	if (__reserved_mem_check_root(node) != 0) {
>  		pr_err("Reserved memory: unsupported node format, ignoring\n");
> +		total_reserved_mem_cnt = 0;
>  		return -EINVAL;
>  	}

[Severity: High]
This is a pre-existing issue, but does this code overflow the dynamic_nodes[]
array?

Looking further down in the fdt_for_each_subnode() loop in
fdt_scan_reserved_mem():

		if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) {
			dynamic_nodes[dynamic_nodes_cnt] = child;
			dynamic_nodes_cnt++;
		}

The dynamic_nodes array is allocated on the stack with a fixed size of
MAX_RESERVED_REGIONS, but there doesn't appear to be a bounds check on
dynamic_nodes_cnt before saving dynamically-placed regions.

Could a misconfigured or malicious device tree with more than
MAX_RESERVED_REGIONS dynamically-placed regions cause an out-of-bounds
write on the stack during the device tree scan?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260527032917.3385849-1-chenwandun1@gmail.com?part=4

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

* Re: [PATCH v3 10/11] riscv: kdump: exclude non-dumpable reserved memory regions from vmcore
  2026-05-27  3:29 ` [PATCH v3 10/11] riscv: " Wandun Chen
@ 2026-05-27  4:05   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-05-27  4:05 UTC (permalink / raw)
  To: Wandun Chen; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] A Time-of-Check to Time-of-Use (TOCTOU) race condition during memory hotplug can lead to an out-of-bounds heap write when populating the crash_mem array.
--

commit a3046cf8f5e5d648fc54675ac919081b37df020f
Author: Wandun Chen <chenwandun@lixiang.com>

riscv: kdump: exclude non-dumpable reserved memory regions from vmcore

This commit applies non-dumpable reserved memory filtering to RISC-V kdump
by dropping flagged regions from the elfcorehdr PT_LOAD segments. It
calculates the needed ranges and excludes them during ELF header preparation.

> diff --git a/arch/riscv/kernel/machine_kexec_file.c b/arch/riscv/kernel/machine_kexec_file.c
> index 54e2d9552e930..c359cf714c791 100644
> --- a/arch/riscv/kernel/machine_kexec_file.c
> +++ b/arch/riscv/kernel/machine_kexec_file.c

[ ... ]

> @@ -63,6 +64,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
>  
>  	nr_ranges = 1; /* For exclusion of crashkernel region */
>  	walk_system_ram_res(0, -1, &nr_ranges, get_nr_ram_ranges_callback);
> +	nr_ranges += of_reserved_mem_kdump_nr_ranges();
>  
>  	cmem = kmalloc_flex(*cmem, ranges, nr_ranges);

[Severity: High]
This is a pre-existing issue, but could this sequence be susceptible to a race
condition during memory hotplug?

In prepare_elf_headers(), walk_system_ram_res() is called here to calculate
nr_ranges, and then called again later to populate the cmem->ranges array.
Because get_online_mems() is not held across these two calls, a new memory
region could be hot-added between them.

Since prepare_elf64_ram_headers_callback() lacks bounds checking and
unconditionally writes to cmem->ranges[cmem->nr_ranges], would a hot-add
event cause the second walk to exceed the newly allocated cmem->max_nr_ranges
and result in an out-of-bounds heap write?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260527032917.3385849-1-chenwandun1@gmail.com?part=10

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

* Re: [PATCH v3 11/11] loongarch: kdump: exclude non-dumpable reserved memory regions from vmcore
  2026-05-27  3:29 ` [PATCH v3 11/11] loongarch: " Wandun Chen
@ 2026-05-27  4:12   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-05-27  4:12 UTC (permalink / raw)
  To: Wandun Chen; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Lockless iteration of memblock regions causes a Time-of-Check to Time-of-Use (TOCTOU) heap buffer overflow and Use-After-Free.
--

commit b3c21375f26da6475c1a19c55f8aa3b310aa8539
Author: Wandun Chen <chenwandun@lixiang.com>
loongarch: kdump: exclude non-dumpable reserved memory regions from vmcore

This commit applies non-dumpable reserved memory filtering to LoongArch kdump.
It uses of_reserved_mem_kdump_exclude() to drop flagged regions from the
elfcorehdr PT_LOAD segments and sizes the crash_mem array accordingly.

> diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
> --- a/arch/loongarch/kernel/machine_kexec_file.c
> +++ b/arch/loongarch/kernel/machine_kexec_file.c
[ ... ]
> @@ -67,6 +68,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
>  	nr_ranges = 2; /* for exclusion of crashkernel region */
>  	for_each_mem_range(i, &start, &end)
>  		nr_ranges++;
> +	nr_ranges += of_reserved_mem_kdump_nr_ranges();
>  
>  	cmem = kmalloc_flex(*cmem, ranges, nr_ranges);

[Severity: High]
This isn't a bug introduced by this patch, but is it possible for a concurrent
memory hotplug operation to cause a use-after-free or buffer overflow here?

Since prepare_elf_headers() executes in process context during the
kexec_file_load syscall, it iterates over memblock.memory via
for_each_mem_range() without holding get_online_mems() or other memory
hotplug locks.

On LoongArch, CONFIG_ARCH_KEEP_MEMBLOCK is enabled, meaning memblock is not
discarded after boot. Concurrent memory hotplug operations can invoke
add_memory_resource(), which calls memblock_add_node() and subsequently
memblock_double_array(). Since slab_is_available() is true at runtime, this
allocates a new array and calls kfree() on the old memblock.memory.regions
array, which could lead to a use-after-free during the lockless iteration.

Additionally, is there a time-of-check to time-of-use race?

The first loop locklessly counts regions to size the cmem array. If memory is
hotplugged between the counting loop and the second population loop, the
second loop will iterate more times than the allocated size.

Without bounds checks before adding entries to cmem->ranges, could this
overflow the kernel heap buffer?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260527032917.3385849-1-chenwandun1@gmail.com?part=11

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

* Re: [PATCH v3 05/11] of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late()
  2026-05-27  3:29 ` [PATCH v3 05/11] of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late() Wandun Chen
@ 2026-05-27  4:21   ` sashiko-bot
  0 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-05-27  4:21 UTC (permalink / raw)
  To: Wandun Chen; +Cc: devicetree, conor+dt, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Stack buffer overflow in fdt_scan_reserved_mem() due to unchecked dynamic_nodes array indexing.
--

commit 6c1b6f45075047e4a90f8ee8101ddc1537a9969a
Author: Wandun Chen <chenwandun@lixiang.com>

of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late()

This patch separates alloc_reserved_mem_array() from
fdt_scan_reserved_mem_late() so that dynamic allocation of the reserved_mem
array happens regardless of whether the device tree contains a
/reserved-memory node. This prepares the subsystem to safely store
/memreserve/ entries.

[ ... ]

> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
> index 0ae16da066e2c..50e5a533e0591 100644
> --- a/drivers/of/of_private.h
> +++ b/drivers/of/of_private.h
> @@ -187,6 +187,7 @@ static inline struct device_node *__of_get_dma_parent(const struct device_node *
>  
>  int fdt_scan_reserved_mem(void);

[Severity: Critical]
This isn't a bug introduced by this patch, but while looking at the reserved
memory code, I noticed a pre-existing issue in fdt_scan_reserved_mem().

Can this code overflow the dynamic_nodes[] array?

drivers/of/of_reserved_mem.c:fdt_scan_reserved_mem() {
    ...
	int dynamic_nodes_cnt = 0, count = 0;
	int dynamic_nodes[MAX_RESERVED_REGIONS];
    ...
	fdt_for_each_subnode(child, fdt, node) {
        ...
		if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) {
			dynamic_nodes[dynamic_nodes_cnt] = child;
			dynamic_nodes_cnt++;
		}
	}
    ...
}

If a device tree provided by a bootloader or via kexec contains more than
MAX_RESERVED_REGIONS (64) dynamic reserved memory regions, would the unchecked
increment of dynamic_nodes_cnt overflow this stack buffer and potentially
lead to memory corruption during early boot?

>  void __init fdt_scan_reserved_mem_late(void);
> +bool __init alloc_reserved_mem_array(void);
>  
>  bool of_fdt_device_is_available(const void *blob, unsigned long node);
>  

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260527032917.3385849-1-chenwandun1@gmail.com?part=5

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

end of thread, other threads:[~2026-05-27  4:21 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-27  3:29 [PATCH v3 00/11] kdump: reduce vmcore size and capture time Wandun Chen
2026-05-27  3:29 ` [PATCH v3 01/11] of: reserved_mem: handle NULL name in of_reserved_mem_lookup() Wandun Chen
2026-05-27  3:29 ` [PATCH v3 02/11] kexec/crash: provide crash_exclude_mem_range() stub when CONFIG_CRASH_DUMP=n Wandun Chen
2026-05-27  3:29 ` [PATCH v3 03/11] of: reserved_mem: avoid post-init UAF when alloc_reserved_mem_array() fails Wandun Chen
2026-05-27  3:29 ` [PATCH v3 04/11] of: reserved_mem: zero total_reserved_mem_cnt if no valid /reserved-memory entry Wandun Chen
2026-05-27  3:53   ` sashiko-bot
2026-05-27  3:29 ` [PATCH v3 05/11] of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late() Wandun Chen
2026-05-27  4:21   ` sashiko-bot
2026-05-27  3:29 ` [PATCH v3 06/11] of: reserved_mem: add dumpable flag to opt-in vmcore Wandun Chen
2026-05-27  3:29 ` [PATCH v3 07/11] of: reserved_mem: save /memreserve/ entries into the reserved_mem array Wandun Chen
2026-05-27  3:29 ` [PATCH v3 08/11] of: reserved_mem: add kdump helpers to exclude non-dumpable regions Wandun Chen
2026-05-27  3:29 ` [PATCH v3 09/11] arm64: kdump: exclude non-dumpable reserved memory regions from vmcore Wandun Chen
2026-05-27  3:29 ` [PATCH v3 10/11] riscv: " Wandun Chen
2026-05-27  4:05   ` sashiko-bot
2026-05-27  3:29 ` [PATCH v3 11/11] loongarch: " Wandun Chen
2026-05-27  4:12   ` sashiko-bot

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