public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump
@ 2026-04-29  6:58 Chen Wandun
  2026-04-29  6:58 ` [PATCH 01/11] of: reserved_mem: fix region count for nodes with multiple reg entries Chen Wandun
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

This series has two parts:

 - Patches 1-4 are OF reserved_mem bug fixes and small hardening
   changes. They stand on their own and at the same time prepare the
   ground for the feature work that follows (accurate region counts,
   consistent two-pass save/reserve state, and an early-out when the
   array is empty).

 - Patches 5-11 introduce a new 'linux,no-dump' reserved-memory
   device tree property and the kdump plumbing to honour it, split
   further as:

     * Patches 5-7: core OF changes - parse 'linux,no-dump' on
       /reserved-memory/ children, save /memreserve/ firmware regions
       into reserved_mem[] with no_dump defaulted on, and add generic
       no-dump crash_mem exclusion helpers.

     * Patches 8-10: arch kdump consumers - arm64, riscv and
       loongarch each call the helpers from patch 7 in their
       prepare_elf_headers() so that 'linux,no-dump' /reserved-memory/
       children and /memreserve/ regions are filtered out of the
       vmcore ELF PT_LOAD segments.

     * Patch 11: user-facing documentation in
       Documentation/admin-guide/kdump/kdump.rst.

Motivation
==========

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. On a
machine with several hundred MiB of such carveouts, the overhead per
vmcore is substantial.

This series adds a declarative way for DT authors to mark such
regions:

    reserved-memory {
        npu_fw@a0000000 {
            reg = <0x0 0xa0000000 0x0 0x10000000>;
            linux,no-dump;
        };
    };

and also defaults /memreserve/ firmware regions (Trusted Firmware /
BL31 images, secondary-CPU spin-table pens, bootloader scratch per
Documentation/arch/arm64/booting.rst and upstream DTS files) to
no_dump=true.

Interaction with existing reserved-memory flags is kept simple:
'linux,no-dump' is an OS hint, it is redundant (but harmless) when
combined with 'no-map' and silently ignored on 'reusable' (CMA)
regions whose contents are relevant for crash analysis. The 'linux,'
prefix follows existing precedents like 'linux,cma-default' since
kdump is a Linux-specific concept.

Benefits
========

 - Smaller vmcore. The excluded firmware carveouts are omitted from
   the ELF PT_LOAD segments entirely, so the resulting dump file is
   smaller by roughly the sum of the tagged regions - on SoCs with
   hundreds of MiB of GPU/DSP/modem/NPU carveouts this is a
   substantial saving, both on disk and in transit to a dump server.

 - Faster kdump. The dump-capture kernel writes less data to storage
   or over the network, which directly shortens the crash-to-dump
   turnaround. Tools that walk the dump (makedumpfile, crash) also
   spend less time on regions that were never going to be useful
   anyway.

 - No existing behaviour change for DTs that do not opt in: regions
   without 'linux,no-dump' and systems without /memreserve/ entries
   are dumped exactly as before.

DT binding
==========

The 'linux,no-dump' property is maintained in dt-schema
(reserved-memory.yaml moved there from the kernel tree).
Corresponding PR:

  https://github.com/devicetree-org/dt-schema/pull/193

Follow-ups
==========

 - powerpc also uses kexec_file and /reserved-memory/, but its
   arch/powerpc/kexec/ranges.c uses the _guarded variant of
   crash_exclude_mem_range with dynamic realloc and collects
   additional RTAS/OPAL firmware ranges. Adapting it needs a small
   extra helper; left as a follow-up.

---

Chen Wandun (11):
  of: reserved_mem: fix region count for nodes with multiple reg entries
  of: reserved_mem: reject reserved memory outside physical address
    range
  of: reserved_mem: avoid unconditional save of reg entries in
    fdt_scan_reserved_mem_late()
  of: reserved_mem: skip reserved_mem array allocation when there is
    nothing to save
  of: reserved_mem: add linux,no-dump property support for reserved
    memory regions
  of: reserved_mem: save /memreserve/ entries into reserved_mem array
  of: reserved_mem: add no-dump crash_mem exclusion helpers
  arm64: kdump: exclude no-dump reserved memory regions from vmcore
  riscv: kdump: exclude no-dump reserved memory regions from vmcore
  loongarch: kdump: exclude no-dump reserved memory regions from vmcore
  Documentation: admin-guide: kdump: document linux,no-dump DT property

 Documentation/admin-guide/kdump/kdump.rst  |  59 ++++++
 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/of_reserved_mem.c               | 233 ++++++++++++++++++---
 include/linux/of_reserved_mem.h            |  16 ++
 6 files changed, 295 insertions(+), 29 deletions(-)

-- 
2.43.0



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

* [PATCH 01/11] of: reserved_mem: fix region count for nodes with multiple reg entries
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 02/11] of: reserved_mem: reject reserved memory outside physical address range Chen Wandun
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

When a reserved-memory node contains multiple reg entries (e.g.,
reg = <base1 size1>, <base2 size2>), the count used for
total_reserved_mem_cnt is wrong in two places:

1) __reserved_mem_reserve_reg() returns 0 on success regardless of how
   many regions it reserved in memblock. The caller in
   fdt_scan_reserved_mem() then increments count by just 1.

2) fdt_scan_reserved_mem_late() uses of_flat_dt_get_addr_size() which
   only reads the first reg entry. Subsequent entries are never
   initialized via fdt_init_reserved_mem_node(), so their metadata is
   lost.

Fix both issues:
 - Make __reserved_mem_reserve_reg() return the actual number of
   regions successfully reserved. Update the caller to accumulate
   the returned count.
 - Rewrite fdt_scan_reserved_mem_late() to use
   of_flat_dt_get_addr_size_prop() and iterate all reg entries,
   initializing each one via fdt_init_reserved_mem_node().

Fixes: 8a6e02d0c00e ("of: reserved_mem: Restructure how the reserved memory regions are processed")
Fixes: 00c9a452a235 ("of: reserved_mem: Add code to dynamically allocate reserved_mem array")
Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
 drivers/of/of_reserved_mem.c | 37 +++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 8d5777cb5d1b..9d1b0193864c 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -129,6 +129,8 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base,
 
 /*
  * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
+ *
+ * Returns: number of regions successfully reserved, or negative error code
  */
 static int __init __reserved_mem_reserve_reg(unsigned long node,
 					     const char *uname)
@@ -137,6 +139,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
 	int i, len, err;
 	const __be32 *prop;
 	bool nomap;
+	int reserved_count = 0;
 
 	prop = of_flat_dt_get_addr_size_prop(node, "reg", &len);
 	if (!prop)
@@ -160,12 +163,13 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
 			fdt_fixup_reserved_mem_node(node, base, size);
 			pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
 				uname, &base, (unsigned long)(size / SZ_1M));
+			reserved_count++;
 		} else {
 			pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
 			       uname, &base, (unsigned long)(size / SZ_1M));
 		}
 	}
-	return 0;
+	return reserved_count;
 }
 
 /*
@@ -275,25 +279,32 @@ void __init fdt_scan_reserved_mem_late(void)
 
 	fdt_for_each_subnode(child, fdt, node) {
 		const char *uname;
-		u64 b, s;
+		int i, len;
+		const __be32 *prop;
 		int ret;
 
 		if (!of_fdt_device_is_available(fdt, child))
 			continue;
 
-		if (!of_flat_dt_get_addr_size(child, "reg", &b, &s))
+		prop = of_flat_dt_get_addr_size_prop(child, "reg", &len);
+		if (!prop)
 			continue;
 
 		ret = fdt_validate_reserved_mem_node(child, NULL);
 		if (ret && ret != -ENODEV)
 			continue;
 
-		base = b;
-		size = s;
+		uname = fdt_get_name(fdt, child, NULL);
+		for (i = 0; i < len; i++) {
+			u64 b, s;
 
-		if (size) {
-			uname = fdt_get_name(fdt, child, NULL);
-			fdt_init_reserved_mem_node(child, uname, base, size);
+			of_flat_dt_read_addr_size(prop, i, &b, &s);
+
+			base = b;
+			size = s;
+
+			if (size)
+				fdt_init_reserved_mem_node(child, uname, base, size);
 		}
 	}
 
@@ -331,16 +342,16 @@ int __init fdt_scan_reserved_mem(void)
 
 	fdt_for_each_subnode(child, fdt, node) {
 		const char *uname;
-		int err;
+		int ret;
 
 		if (!of_fdt_device_is_available(fdt, child))
 			continue;
 
 		uname = fdt_get_name(fdt, child, NULL);
 
-		err = __reserved_mem_reserve_reg(child, uname);
-		if (!err)
-			count++;
+		ret = __reserved_mem_reserve_reg(child, uname);
+		if (ret > 0)
+			count += ret;
 		/*
 		 * Save the nodes for the dynamically-placed regions
 		 * into an array which will be used for allocation right
@@ -348,7 +359,7 @@ int __init fdt_scan_reserved_mem(void)
 		 * or marked as no-map. This is done to avoid dynamically
 		 * allocating from one of the statically-placed regions.
 		 */
-		if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) {
+		if (ret == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) {
 			dynamic_nodes[dynamic_nodes_cnt] = child;
 			dynamic_nodes_cnt++;
 		}
-- 
2.43.0



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

* [PATCH 02/11] of: reserved_mem: reject reserved memory outside physical address range
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
  2026-04-29  6:58 ` [PATCH 01/11] of: reserved_mem: fix region count for nodes with multiple reg entries Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 03/11] of: reserved_mem: avoid unconditional save of reg entries in fdt_scan_reserved_mem_late() Chen Wandun
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

early_init_dt_reserve_memory() does not validate whether the region
falls within physical memory. If a device tree incorrectly specifies a
reserved memory region outside the physical address range:

 - For the non-nomap path, memblock_reserve() blindly adds the region
   to memblock.reserved, creating a stale entry that refers to
   non-existent memory.

 - For the nomap path, memblock_mark_nomap() silently fails to match
   any region in memblock.memory, but still returns success.

Add a memblock_overlaps_region() check at the entry of
early_init_dt_reserve_memory() to reject such regions before any
memblock operation takes place. This also simplifies the existing nomap
guard: the original "overlaps && is_reserved" condition reduces to just
"is_reserved", since the overlap with physical memory is already
guaranteed by the new check.

Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
 drivers/of/of_reserved_mem.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 9d1b0193864c..03c676052dab 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -112,14 +112,21 @@ static int fdt_fixup_reserved_mem_node(unsigned long node,
 static int __init early_init_dt_reserve_memory(phys_addr_t base,
 					       phys_addr_t size, bool nomap)
 {
+	if (!memblock_overlaps_region(&memblock.memory, base, size)) {
+		phys_addr_t end = base + size - 1;
+
+		pr_warn("Reserved memory region %pa..%pa is outside of physical memory\n",
+			&base, &end);
+		return -EINVAL;
+	}
+
 	if (nomap) {
 		/*
 		 * If the memory is already reserved (by another region), we
-		 * should not allow it to be marked nomap, but don't worry
-		 * if the region isn't memory as it won't be mapped.
+		 * should not allow it to be marked nomap. The region being
+		 * physical memory is guaranteed by the overlap check above.
 		 */
-		if (memblock_overlaps_region(&memblock.memory, base, size) &&
-		    memblock_is_region_reserved(base, size))
+		if (memblock_is_region_reserved(base, size))
 			return -EBUSY;
 
 		return memblock_mark_nomap(base, size);
-- 
2.43.0



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

* [PATCH 03/11] of: reserved_mem: avoid unconditional save of reg entries in fdt_scan_reserved_mem_late()
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
  2026-04-29  6:58 ` [PATCH 01/11] of: reserved_mem: fix region count for nodes with multiple reg entries Chen Wandun
  2026-04-29  6:58 ` [PATCH 02/11] of: reserved_mem: reject reserved memory outside physical address range Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 04/11] of: reserved_mem: skip reserved_mem array allocation when there is nothing to save Chen Wandun
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

fdt_scan_reserved_mem_late() iterates all reg entries of every
/reserved-memory child and unconditionally initialises each via
fdt_init_reserved_mem_node(), while fdt_scan_reserved_mem() in the
first pass may have rejected individual entries in
early_init_dt_reserve_memory() (e.g. outside physical memory or, on
the no-map path, overlapping an existing reservation).

When a single node mixes failing and succeeding reg entries, the
first-pass counter only accounts for the successful ones, and the
second-pass save then overflows into the wrong slots: the failing
entry may be written to reserved_mem[] while the succeeding one is
dropped by the "not enough space" guard in fdt_init_reserved_mem_node().
The stored entry does not correspond to any real memblock reservation
and misleads consumers such as of_reserved_mem_lookup().

Mirror early_init_dt_reserve_memory()'s preconditions in the
per-reg-entry save loop:

 - skip the entry if it does not overlap memblock.memory;
 - for nomap entries, skip if the region is already reserved.

This keeps reserved_mem[] strictly consistent with the regions that
were actually reserved.

Fixes: 8a6e02d0c00e ("of: reserved_mem: Restructure how the reserved memory regions are processed")
Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
 drivers/of/of_reserved_mem.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 03c676052dab..807b222fce5f 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -288,6 +288,7 @@ void __init fdt_scan_reserved_mem_late(void)
 		const char *uname;
 		int i, len;
 		const __be32 *prop;
+		bool nomap;
 		int ret;
 
 		if (!of_fdt_device_is_available(fdt, child))
@@ -301,6 +302,7 @@ void __init fdt_scan_reserved_mem_late(void)
 		if (ret && ret != -ENODEV)
 			continue;
 
+		nomap = of_get_flat_dt_prop(child, "no-map", NULL) != NULL;
 		uname = fdt_get_name(fdt, child, NULL);
 		for (i = 0; i < len; i++) {
 			u64 b, s;
@@ -310,8 +312,23 @@ void __init fdt_scan_reserved_mem_late(void)
 			base = b;
 			size = s;
 
-			if (size)
-				fdt_init_reserved_mem_node(child, uname, base, size);
+			if (!size)
+				continue;
+
+			/*
+			 * Save only entries that were successfully reserved
+			 * in the first pass. Mirrors the preconditions in
+			 * early_init_dt_reserve_memory() so that a per-reg
+			 * entry failure (outside RAM, or nomap rejected due
+			 * to an existing reservation) does not leave a
+			 * ghost slot in reserved_mem[].
+			 */
+			if (!memblock_overlaps_region(&memblock.memory, base, size))
+				continue;
+			if (nomap && memblock_is_region_reserved(base, size))
+				continue;
+
+			fdt_init_reserved_mem_node(child, uname, base, size);
 		}
 	}
 
-- 
2.43.0



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

* [PATCH 04/11] of: reserved_mem: skip reserved_mem array allocation when there is nothing to save
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
                   ` (2 preceding siblings ...)
  2026-04-29  6:58 ` [PATCH 03/11] of: reserved_mem: avoid unconditional save of reg entries in fdt_scan_reserved_mem_late() Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 05/11] of: reserved_mem: add linux,no-dump property support for reserved memory regions Chen Wandun
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

fdt_scan_reserved_mem_late() unconditionally calls
alloc_reserved_mem_array() after confirming /reserved-memory exists.
Two issues with that:

 - When __reserved_mem_check_root() subsequently fails, the call
   returns right away, leaving the freshly allocated array unused.
 - When /reserved-memory exists but fdt_scan_reserved_mem() found no
   entries to save (total_reserved_mem_cnt stays at its freshly-set
   value of zero, e.g. empty node or all children disabled),
   alloc_reserved_mem_array() ends up calling memblock_alloc() with
   zero size, which returns NULL and logs an "Failed to allocate
   memory for reserved_mem array" error even though nothing was
   expected to be allocated.

Move alloc_reserved_mem_array() past the root-node check and gate it
on total_reserved_mem_cnt, so the array is only allocated when there
is at least one entry that needs a slot.

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

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 807b222fce5f..93585af9f8a3 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -276,14 +276,22 @@ void __init fdt_scan_reserved_mem_late(void)
 		return;
 	}
 
-	/* Attempt dynamic allocation of a new reserved_mem array */
-	alloc_reserved_mem_array();
-
 	if (__reserved_mem_check_root(node)) {
 		pr_err("Reserved memory: unsupported node format, ignoring\n");
 		return;
 	}
 
+	/*
+	 * fdt_scan_reserved_mem() sets total_reserved_mem_cnt to the
+	 * number of entries that need a slot in reserved_mem[]. If it is
+	 * zero there is nothing to allocate or save.
+	 */
+	if (!total_reserved_mem_cnt)
+		return;
+
+	/* Attempt dynamic allocation of a new reserved_mem array */
+	alloc_reserved_mem_array();
+
 	fdt_for_each_subnode(child, fdt, node) {
 		const char *uname;
 		int i, len;
-- 
2.43.0



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

* [PATCH 05/11] of: reserved_mem: add linux,no-dump property support for reserved memory regions
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
                   ` (3 preceding siblings ...)
  2026-04-29  6:58 ` [PATCH 04/11] of: reserved_mem: skip reserved_mem array allocation when there is nothing to save Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 06/11] of: reserved_mem: save /memreserve/ entries into reserved_mem array Chen Wandun
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

Add a 'no_dump' field to struct reserved_mem and parse the
'linux,no-dump' device tree property during reserved memory node
initialization. This property allows device tree authors to mark
specific reserved memory regions that should be excluded from kdump
vmcore dumps.

Reserved memory regions used by device firmware (e.g., GPU, DSP, modem)
typically contain data that is not useful for kernel crash analysis and
can significantly increase vmcore size. The 'linux,no-dump' property
provides a declarative way to indicate these regions should be filtered
out when constructing the elfcorehdr for kdump.

The property is named with a 'linux,' prefix because kdump/vmcore is
Linux-specific and the property is an OS hint rather than a hardware
description, matching existing properties such as 'linux,cma-default'
and 'linux,usable-memory-range'.

The 'linux,no-dump' property is only effective when the region:
 - Does not have 'no-map': these regions are already excluded from
   vmcore since they are removed from the linear mapping (MEMBLOCK_NOMAP).
 - Does not have 'reusable': CMA reusable regions are actively used by
   the kernel for movable page allocations, and their contents are
   valuable for crash analysis.

The no-dump status is also printed in the boot log alongside the
existing nomap and reusable flags for diagnostic purposes.

Corresponding dt-schema binding update:
  https://github.com/devicetree-org/dt-schema/pull/193

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

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 93585af9f8a3..ac3d8b837d61 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -654,6 +654,7 @@ static void __init fdt_init_reserved_mem_node(unsigned long node, const char *un
 {
 	int err = 0;
 	bool nomap;
+	bool reusable;
 
 	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
 
@@ -662,11 +663,14 @@ static void __init fdt_init_reserved_mem_node(unsigned long node, const char *un
 		return;
 	}
 
+	nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
+	reusable = of_get_flat_dt_prop(node, "reusable", NULL) != NULL;
+
 	rmem->name = uname;
 	rmem->base = base;
 	rmem->size = size;
-
-	nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
+	rmem->no_dump = !nomap && !reusable &&
+			of_get_flat_dt_prop(node, "linux,no-dump", NULL) != NULL;
 
 	err = __reserved_mem_init_node(rmem, node);
 	if (err != 0 && err != -ENODEV) {
@@ -680,13 +684,12 @@ static void __init fdt_init_reserved_mem_node(unsigned long node, const char *un
 		return;
 	} else {
 		phys_addr_t end = rmem->base + rmem->size - 1;
-		bool reusable =
-			(of_get_flat_dt_prop(node, "reusable", NULL)) != NULL;
 
-		pr_info("%pa..%pa (%lu KiB) %s %s %s\n",
+		pr_info("%pa..%pa (%lu KiB) %s %s %s %s\n",
 			&rmem->base, &end, (unsigned long)(rmem->size / SZ_1K),
 			nomap ? "nomap" : "map",
 			reusable ? "reusable" : "non-reusable",
+			rmem->no_dump ? "no-dump" : "dump",
 			rmem->name ? rmem->name : "unknown");
 	}
 
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index e8b20b29fa68..29674f572673 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				no_dump;
 };
 
 struct reserved_mem_ops {
-- 
2.43.0



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

* [PATCH 06/11] of: reserved_mem: save /memreserve/ entries into reserved_mem array
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
                   ` (4 preceding siblings ...)
  2026-04-29  6:58 ` [PATCH 05/11] of: reserved_mem: add linux,no-dump property support for reserved memory regions Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 07/11] of: reserved_mem: add no-dump crash_mem exclusion helpers Chen Wandun
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

Save /memreserve/ entries from the FDT header into the reserved_mem
array so they can be consumed as vmcore filtering metadata by kdump.

/memreserve/ regions hold firmware or bootloader state that is not
useful for kernel crash analysis, so saved /memreserve/ entries
default to no_dump=true and are tagged with name="memreserve" so
consumers can distinguish them from /reserved-memory/ child nodes.

Some DTBs declare the same or overlapping range in both
/memreserve/ and a /reserved-memory/ child. Commit b41328187629
("of: fdt: Scan /memreserve/ last") describes one such case on
Khadas Vim3 where the range is in /memreserve/ and also in a
/reserved-memory/ child carrying no-map. The /reserved-memory/
node's attributes (no-map, reusable, linux,no-dump) are the
explicit declaration and must win over the firmware default,
fdt_reserved_mem_save_memreserve() therefore inherits no_dump from
the overlapping /reserved-memory/ entry rather than silently
applying no_dump=true.

Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
 drivers/of/of_reserved_mem.c | 107 +++++++++++++++++++++++++++++------
 1 file changed, 91 insertions(+), 16 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index ac3d8b837d61..4b80420da2d2 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -252,6 +252,49 @@ static void __init __rmem_check_for_overlap(void)
 	}
 }
 
+/**
+ * fdt_reserved_mem_save_memreserve() - save a /memreserve/ entry
+ * @base: base address
+ * @size: size
+ *
+ * Save a /memreserve/ range into reserved_mem[] with no_dump=true
+ * as the firmware default. If the range overlaps a /reserved-memory/
+ * child already saved in this pass, inherit that entry's no_dump so
+ * node-level attributes (no-map, reusable, linux,no-dump) win over
+ * the firmware default.
+ */
+static void __init fdt_reserved_mem_save_memreserve(phys_addr_t base,
+						    phys_addr_t size)
+{
+	struct reserved_mem *rmem;
+	phys_addr_t end = base + size;
+	bool no_dump = true;
+	int i;
+
+	for (i = 0; i < reserved_mem_count; i++) {
+		phys_addr_t r_base = reserved_mem[i].base;
+		phys_addr_t r_end = r_base + reserved_mem[i].size;
+
+		if (base < r_end && end > r_base) {
+			no_dump = reserved_mem[i].no_dump;
+			break;
+		}
+	}
+
+	if (reserved_mem_count == total_reserved_mem_cnt) {
+		pr_err("not enough space for all defined regions.\n");
+		return;
+	}
+
+	rmem = &reserved_mem[reserved_mem_count];
+	rmem->name = "memreserve";
+	rmem->base = base;
+	rmem->size = size;
+	rmem->no_dump = no_dump;
+
+	reserved_mem_count++;
+}
+
 /**
  * fdt_scan_reserved_mem_late() - Scan FDT and initialize remaining reserved
  * memory regions.
@@ -260,6 +303,9 @@ static void __init __rmem_check_for_overlap(void)
  * "static" reserved memory regions, that are defined using the "reg"
  * property. Each such region is then initialized with its specific init
  * function and stored in the global reserved_mem array.
+ *
+ * In addition, /memreserve/ entries from the FDT header are saved into
+ * the reserved_mem array so they can be consumed as vmcore metadata.
  */
 void __init fdt_scan_reserved_mem_late(void)
 {
@@ -270,28 +316,32 @@ void __init fdt_scan_reserved_mem_late(void)
 	if (!fdt)
 		return;
 
+	/*
+	 * fdt_scan_reserved_mem() has set total_reserved_mem_cnt to the
+	 * total number of entries to be saved (reg-based + /memreserve/).
+	 * If it is zero there is nothing to allocate, save or check.
+	 */
+	if (!total_reserved_mem_cnt)
+		return;
+
+	/*
+	 * Allocate up front: /memreserve/ saves below may run on any
+	 * path and must write into a memblock-backed array, not the
+	 * __initdata reserved_mem_array which is freed at free_initmem().
+	 */
+	alloc_reserved_mem_array();
+
 	node = fdt_path_offset(fdt, "/reserved-memory");
 	if (node < 0) {
 		pr_info("Reserved memory: No reserved-memory node in the DT\n");
-		return;
+		goto memreserve;
 	}
 
 	if (__reserved_mem_check_root(node)) {
 		pr_err("Reserved memory: unsupported node format, ignoring\n");
-		return;
+		goto memreserve;
 	}
 
-	/*
-	 * fdt_scan_reserved_mem() sets total_reserved_mem_cnt to the
-	 * number of entries that need a slot in reserved_mem[]. If it is
-	 * zero there is nothing to allocate or save.
-	 */
-	if (!total_reserved_mem_cnt)
-		return;
-
-	/* Attempt dynamic allocation of a new reserved_mem array */
-	alloc_reserved_mem_array();
-
 	fdt_for_each_subnode(child, fdt, node) {
 		const char *uname;
 		int i, len;
@@ -342,6 +392,18 @@ void __init fdt_scan_reserved_mem_late(void)
 
 	/* check for overlapping reserved regions */
 	__rmem_check_for_overlap();
+
+memreserve:
+	/* Save /memreserve/ entries (independent of /reserved-memory) */
+	for (int i = 0; ; i++) {
+		u64 mbase, msize;
+
+		if (fdt_get_mem_rsv(fdt, i, &mbase, &msize))
+			break;
+		if (!msize)
+			break;
+		fdt_reserved_mem_save_memreserve(mbase, msize);
+	}
 }
 
 static int __init __reserved_mem_alloc_size(unsigned long node, const char *uname);
@@ -365,11 +427,11 @@ int __init fdt_scan_reserved_mem(void)
 
 	node = fdt_path_offset(fdt, "/reserved-memory");
 	if (node < 0)
-		return -ENODEV;
+		goto memreserve;
 
 	if (__reserved_mem_check_root(node) != 0) {
 		pr_err("Reserved memory: unsupported node format, ignoring\n");
-		return -EINVAL;
+		goto memreserve;
 	}
 
 	fdt_for_each_subnode(child, fdt, node) {
@@ -406,8 +468,21 @@ int __init fdt_scan_reserved_mem(void)
 		if (!err)
 			count++;
 	}
+
+memreserve:
+	/* Count /memreserve/ entries (independent of /reserved-memory) */
+	for (int i = 0; ; i++) {
+		u64 base, size;
+
+		if (fdt_get_mem_rsv(fdt, i, &base, &size))
+			break;
+		if (!size)
+			break;
+		count++;
+	}
+
 	total_reserved_mem_cnt = count;
-	return 0;
+	return count ? 0 : -ENODEV;
 }
 
 /*
-- 
2.43.0



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

* [PATCH 07/11] of: reserved_mem: add no-dump crash_mem exclusion helpers
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
                   ` (5 preceding siblings ...)
  2026-04-29  6:58 ` [PATCH 06/11] of: reserved_mem: save /memreserve/ entries into reserved_mem array Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 08/11] arm64: kdump: exclude no-dump reserved memory regions from vmcore Chen Wandun
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

Provide two kdump-oriented helpers so that arch kexec_file code does
not have to open-code the no-dump filtering loop:

 - of_reserved_mem_no_dump_nr_ranges() returns the number of reserved
   regions flagged with linux,no-dump. Each exclusion may split one
   existing crash_mem range into two, so callers use this count to
   pre-size their crash_mem allocation.

 - of_reserved_mem_exclude_no_dump() walks the reserved_mem[] array
   and calls crash_exclude_mem_range() for each no-dump region.

Both helpers are guarded by CONFIG_KEXEC_FILE; empty inline stubs are
provided for the !KEXEC_FILE case so architecture code can call them
unconditionally.

The consumers are added in the following arm64, riscv and loongarch
patches in this series.

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

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 4b80420da2d2..038056a6408a 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -27,6 +27,10 @@
 
 #include "of_private.h"
 
+#ifdef CONFIG_KEXEC_FILE
+#include <linux/crash_core.h>
+#endif
+
 static struct reserved_mem reserved_mem_array[MAX_RESERVED_REGIONS] __initdata;
 static struct reserved_mem *reserved_mem __refdata = reserved_mem_array;
 static int total_reserved_mem_cnt = MAX_RESERVED_REGIONS;
@@ -916,6 +920,56 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_reserved_mem_lookup);
 
+#ifdef CONFIG_KEXEC_FILE
+/**
+ * of_reserved_mem_no_dump_nr_ranges() - count reserved regions flagged
+ * with the linux,no-dump property.
+ *
+ * Each such region may split an existing crash_mem range into two when
+ * it is excluded, so callers can use this count to pre-size their
+ * crash_mem allocation.
+ */
+unsigned int of_reserved_mem_no_dump_nr_ranges(void)
+{
+	unsigned int i, n = 0;
+
+	for (i = 0; i < reserved_mem_count; i++)
+		if (reserved_mem[i].no_dump)
+			n++;
+	return n;
+}
+
+/**
+ * of_reserved_mem_exclude_no_dump() - exclude no-dump reserved regions
+ * from a crash_mem list.
+ * @cmem: crash memory list to modify
+ *
+ * Walks the reserved_mem[] array and calls crash_exclude_mem_range() for
+ * every region with no_dump set. Intended to be called from arch kdump
+ * code when constructing the elfcorehdr.
+ *
+ * Returns 0 on success, or a negative error returned by
+ * crash_exclude_mem_range() on the first failure.
+ */
+int of_reserved_mem_exclude_no_dump(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->no_dump || !r->size)
+			continue;
+		ret = crash_exclude_mem_range(cmem, r->base,
+					      r->base + r->size - 1);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+#endif /* CONFIG_KEXEC_FILE */
+
 /**
  * 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 29674f572673..cd0f88f29579 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;
@@ -94,6 +95,20 @@ static inline int of_reserved_mem_region_count(const struct device_node *np)
 }
 #endif
 
+#if defined(CONFIG_OF_RESERVED_MEM) && defined(CONFIG_KEXEC_FILE)
+unsigned int of_reserved_mem_no_dump_nr_ranges(void);
+int of_reserved_mem_exclude_no_dump(struct crash_mem *cmem);
+#else
+static inline unsigned int of_reserved_mem_no_dump_nr_ranges(void)
+{
+	return 0;
+}
+static inline int of_reserved_mem_exclude_no_dump(struct crash_mem *cmem)
+{
+	return 0;
+}
+#endif
+
 /**
  * of_reserved_mem_device_init() - assign reserved memory region to given device
  * @dev:	Pointer to the device to configure
-- 
2.43.0



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

* [PATCH 08/11] arm64: kdump: exclude no-dump reserved memory regions from vmcore
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
                   ` (6 preceding siblings ...)
  2026-04-29  6:58 ` [PATCH 07/11] of: reserved_mem: add no-dump crash_mem exclusion helpers Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 09/11] riscv: " Chen Wandun
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

Exclude reserved memory regions marked with the linux,no-dump property
from the elfcorehdr PT_LOAD segments when preparing kdump vmcore.

Device firmware memory regions (e.g., GPU, DSP, modem) reserved via
the device tree typically contain data that is not useful for kernel
crash analysis and can significantly increase vmcore size. By honoring
the no_dump flag in the reserved_mem array, these regions are filtered
out from the crash dump, resulting in smaller and more focused vmcore
files.

Use the common of_reserved_mem_exclude_no_dump() helper to perform the
exclusion, and pre-size the crash_mem array via
of_reserved_mem_no_dump_nr_ranges().

Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <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..7c9c38096c60 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_no_dump_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_exclude_no_dump(cmem);
+	if (ret)
+		goto out;
+
 	ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
 
 out:
-- 
2.43.0



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

* [PATCH 09/11] riscv: kdump: exclude no-dump reserved memory regions from vmcore
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
                   ` (7 preceding siblings ...)
  2026-04-29  6:58 ` [PATCH 08/11] arm64: kdump: exclude no-dump reserved memory regions from vmcore Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 10/11] loongarch: " Chen Wandun
  2026-04-29  6:58 ` [PATCH 11/11] Documentation: admin-guide: kdump: document linux,no-dump DT property Chen Wandun
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

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

Signed-off-by: Chen Wandun <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..012885ac9b79 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_no_dump_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_exclude_no_dump(cmem);
 	if (!ret)
 		ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
 
-- 
2.43.0



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

* [PATCH 10/11] loongarch: kdump: exclude no-dump reserved memory regions from vmcore
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
                   ` (8 preceding siblings ...)
  2026-04-29  6:58 ` [PATCH 09/11] riscv: " Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  2026-04-29  6:58 ` [PATCH 11/11] Documentation: admin-guide: kdump: document linux,no-dump DT property Chen Wandun
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

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

Signed-off-by: Chen Wandun <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..742fb9affcb9 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_no_dump_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_exclude_no_dump(cmem);
+	if (ret < 0)
+		goto out;
+
 	ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
 
 out:
-- 
2.43.0



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

* [PATCH 11/11] Documentation: admin-guide: kdump: document linux,no-dump DT property
  2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
                   ` (9 preceding siblings ...)
  2026-04-29  6:58 ` [PATCH 10/11] loongarch: " Chen Wandun
@ 2026-04-29  6:58 ` Chen Wandun
  10 siblings, 0 replies; 12+ messages in thread
From: Chen Wandun @ 2026-04-29  6:58 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
	linux-riscv, devicetree
  Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
	skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
	aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao

Describe the new 'linux,no-dump' reserved-memory device tree property
and the automatic exclusion of /memreserve/ entries from the kdump
vmcore.

The section covers:

 - The two mechanisms that exclude reserved memory from the vmcore
   (firmware /memreserve/ entries and linux,no-dump child nodes).
 - Intended use cases (firmware-owned GPU, DSP and modem carveouts).
 - Interaction with the existing 'no-map' and 'reusable' flags, with
   the silent-ignore precedence implemented by the kernel.
 - Architectures honouring the hint (arm64, riscv, loongarch).
 - An illustrative reserved-memory DTS snippet.

The DT binding for the property itself is maintained in dt-schema.

Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
---
 Documentation/admin-guide/kdump/kdump.rst | 59 +++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/Documentation/admin-guide/kdump/kdump.rst b/Documentation/admin-guide/kdump/kdump.rst
index 7587caadbae1..c2246888e84d 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -600,6 +600,65 @@ with /sys/kernel/config/crash_dm_crypt_keys for setup,
 3. After the dump-capture kerne get booted, restore the keys to user keyring
    echo yes > /sys/kernel/crash_dm_crypt_keys/restore
 
+Excluding reserved memory regions from the vmcore (device tree)
+===============================================================
+
+On architectures that boot from a device tree and use kexec_file for
+kdump (arm64, riscv, loongarch), specific reserved memory regions can
+be excluded from the ELF PT_LOAD segments of the crash dump.
+
+Two mechanisms contribute to the exclusion:
+
+1) /memreserve/ entries from the FDT header.
+
+   These are firmware-level memory reservations with no associated
+   device tree node and therefore no driver-level description. Their
+   contents are typically firmware scratch areas that carry no value
+   for kernel crash analysis, so they are excluded from the vmcore
+   automatically.
+
+2) Reserved-memory nodes carrying the 'linux,no-dump' property.
+
+   Device tree authors can add this boolean hint to any
+   /reserved-memory child node to request that the kernel skip that
+   region when constructing the elfcorehdr. This is intended for
+   firmware-owned carveouts such as GPU, DSP and modem memory, whose
+   contents tend to significantly inflate the vmcore without aiding
+   kernel crash analysis.
+
+   Example::
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               gpu_fw@a0000000 {
+                       reg = <0x0 0xa0000000 0x0 0x01000000>;
+                       no-map;
+                       linux,no-dump;
+               };
+
+               modem_fw@b0000000 {
+                       reg = <0x0 0xb0000000 0x0 0x02000000>;
+                       linux,no-dump;
+               };
+       };
+
+Interaction with other reserved-memory flags:
+
+- 'no-map': the region is already absent from the kernel linear map,
+  so it does not appear in the vmcore to begin with. Combining
+  'linux,no-dump' with 'no-map' is harmless but redundant.
+
+- 'reusable': the region is actively used by the kernel for movable
+  page allocations (CMA) and its contents are relevant to crash
+  analysis. 'linux,no-dump' is silently ignored on a reusable region.
+
+The property is an operating-system hint; DTBs that do not set it
+retain the legacy behaviour (all memory is dumped). Architectures
+that do not honour the hint simply ignore it.
+
 Contact
 =======
 
-- 
2.43.0



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

end of thread, other threads:[~2026-04-29  7:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-29  6:58 [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump Chen Wandun
2026-04-29  6:58 ` [PATCH 01/11] of: reserved_mem: fix region count for nodes with multiple reg entries Chen Wandun
2026-04-29  6:58 ` [PATCH 02/11] of: reserved_mem: reject reserved memory outside physical address range Chen Wandun
2026-04-29  6:58 ` [PATCH 03/11] of: reserved_mem: avoid unconditional save of reg entries in fdt_scan_reserved_mem_late() Chen Wandun
2026-04-29  6:58 ` [PATCH 04/11] of: reserved_mem: skip reserved_mem array allocation when there is nothing to save Chen Wandun
2026-04-29  6:58 ` [PATCH 05/11] of: reserved_mem: add linux,no-dump property support for reserved memory regions Chen Wandun
2026-04-29  6:58 ` [PATCH 06/11] of: reserved_mem: save /memreserve/ entries into reserved_mem array Chen Wandun
2026-04-29  6:58 ` [PATCH 07/11] of: reserved_mem: add no-dump crash_mem exclusion helpers Chen Wandun
2026-04-29  6:58 ` [PATCH 08/11] arm64: kdump: exclude no-dump reserved memory regions from vmcore Chen Wandun
2026-04-29  6:58 ` [PATCH 09/11] riscv: " Chen Wandun
2026-04-29  6:58 ` [PATCH 10/11] loongarch: " Chen Wandun
2026-04-29  6:58 ` [PATCH 11/11] Documentation: admin-guide: kdump: document linux,no-dump DT property Chen Wandun

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