[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <4dc944c7-20ad-4e92-b05e-28a9e0c5a2b8@linux.ibm.com>
Date: Wed, 4 Feb 2026 18:02:16 +0530
From: Sourabh Jain <sourabhjain@...ux.ibm.com>
To: Jinjie Ruan <ruanjinjie@...wei.com>, corbet@....net,
catalin.marinas@....com, will@...nel.org, chenhuacai@...nel.org,
kernel@...0n.name, maddy@...ux.ibm.com, mpe@...erman.id.au,
npiggin@...il.com, chleroy@...nel.org, pjw@...nel.org,
palmer@...belt.com, aou@...s.berkeley.edu, alex@...ti.fr,
tglx@...nel.org, mingo@...hat.com, bp@...en8.de,
dave.hansen@...ux.intel.com, hpa@...or.com, akpm@...ux-foundation.org,
bhe@...hat.com, vgoyal@...hat.com, dyoung@...hat.com,
pawan.kumar.gupta@...ux.intel.com, feng.tang@...ux.alibaba.com,
kees@...nel.org, elver@...gle.com, arnd@...db.de, lirongqing@...du.com,
fvdl@...gle.com, leitao@...ian.org, rppt@...nel.org,
cfsworks@...il.com, osandov@...com, ardb@...nel.org,
ryan.roberts@....com, tangyouling@...inos.cn, ritesh.list@...il.com,
bjorn@...osinc.com, songshuaishuai@...ylab.org,
samuel.holland@...ive.com, kevin.brodsky@....com,
junhui.liu@...moral.tech, vishal.moola@...il.com, coxu@...hat.com,
jbohac@...e.cz, liaoyuanhong@...o.com, brgerst@...il.com,
fuqiang.wang@...ystack.cn, x86@...nel.org, linux-doc@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
loongarch@...ts.linux.dev, linuxppc-dev@...ts.ozlabs.org,
linux-riscv@...ts.infradead.org, kexec@...ts.infradead.org
Subject: Re: [PATCH v3 1/3] crash: Exclude crash kernel memory in crash core
On 04/02/26 15:07, Jinjie Ruan wrote:
> The exclude of crashk_res, crashk_low_res and crashk_cma memory
> are almost identical across different architectures, so handling them
> in the crash core would eliminate a lot of duplication, so do
> them in the common code.
>
> Signed-off-by: Jinjie Ruan <ruanjinjie@...wei.com>
> ---
> arch/arm64/kernel/machine_kexec_file.c | 12 -------
> arch/loongarch/kernel/machine_kexec_file.c | 12 -------
> arch/powerpc/kexec/ranges.c | 16 ++-------
> arch/riscv/kernel/machine_kexec_file.c | 5 +--
> arch/x86/kernel/crash.c | 39 ++--------------------
> kernel/crash_core.c | 28 ++++++++++++++++
> 6 files changed, 34 insertions(+), 78 deletions(-)
>
> diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
> index 410060ebd86d..ed2c45007158 100644
> --- a/arch/arm64/kernel/machine_kexec_file.c
> +++ b/arch/arm64/kernel/machine_kexec_file.c
> @@ -64,20 +64,8 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
> cmem->nr_ranges++;
> }
>
> - /* Exclude crashkernel region */
> - ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
> - if (ret)
> - goto out;
> -
> - if (crashk_low_res.end) {
> - ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
> - if (ret)
> - goto out;
> - }
> -
> ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
>
> -out:
> kfree(cmem);
> return ret;
> }
> diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
> index fb57026f5f25..26f867e53955 100644
> --- a/arch/loongarch/kernel/machine_kexec_file.c
> +++ b/arch/loongarch/kernel/machine_kexec_file.c
> @@ -80,20 +80,8 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
> cmem->nr_ranges++;
> }
>
> - /* Exclude crashkernel region */
> - ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
> - if (ret < 0)
> - goto out;
> -
> - if (crashk_low_res.end) {
> - ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
> - if (ret < 0)
> - goto out;
> - }
> -
> ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
>
> -out:
> kfree(cmem);
> return ret;
> }
> diff --git a/arch/powerpc/kexec/ranges.c b/arch/powerpc/kexec/ranges.c
> index 867135560e5c..3f76dd266b1f 100644
> --- a/arch/powerpc/kexec/ranges.c
> +++ b/arch/powerpc/kexec/ranges.c
> @@ -553,9 +553,7 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges)
> #endif /* CONFIG_KEXEC_FILE */
>
> #ifdef CONFIG_CRASH_DUMP
> -static int crash_exclude_mem_range_guarded(struct crash_mem **mem_ranges,
> - unsigned long long mstart,
> - unsigned long long mend)
> +static int crash_realloc_mem_range_guarded(struct crash_mem **mem_ranges)
> {
> struct crash_mem *tmem = *mem_ranges;
>
> @@ -566,7 +564,7 @@ static int crash_exclude_mem_range_guarded(struct crash_mem **mem_ranges,
> return -ENOMEM;
> }
>
> - return crash_exclude_mem_range(tmem, mstart, mend);
> + return 0;
> }
>
> /**
> @@ -604,18 +602,10 @@ int get_crash_memory_ranges(struct crash_mem **mem_ranges)
> sort_memory_ranges(*mem_ranges, true);
> }
>
> - /* Exclude crashkernel region */
> - ret = crash_exclude_mem_range_guarded(mem_ranges, crashk_res.start, crashk_res.end);
> + ret = crash_realloc_mem_range_guarded(mem_ranges);
What if max_nr_ranges - nr_ranges = 1, then no realloc will happen here.
And in
elf_header_exclude_ranges we may not enough space to store additional
memory ranges needed while excluding one or more CMA ranges.
> if (ret)
> goto out;
>
> - for (i = 0; i < crashk_cma_cnt; ++i) {
> - ret = crash_exclude_mem_range_guarded(mem_ranges, crashk_cma_ranges[i].start,
> - crashk_cma_ranges[i].end);
> - if (ret)
> - goto out;
> - }
> -
> /*
> * FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
> * regions are exported to save their context at the time of
> diff --git a/arch/riscv/kernel/machine_kexec_file.c b/arch/riscv/kernel/machine_kexec_file.c
> index dd9d92a96517..fec3622a13c9 100644
> --- a/arch/riscv/kernel/machine_kexec_file.c
> +++ b/arch/riscv/kernel/machine_kexec_file.c
> @@ -74,10 +74,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
> if (ret)
> goto out;
>
> - /* Exclude crashkernel region */
> - ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
> - if (!ret)
> - ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
> + ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
>
> out:
> kfree(cmem);
> diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
> index 335fd2ee9766..d8341a48f6b3 100644
> --- a/arch/x86/kernel/crash.c
> +++ b/arch/x86/kernel/crash.c
> @@ -186,41 +186,6 @@ static struct crash_mem *fill_up_crash_elf_data(void)
> return cmem;
> }
>
> -/*
> - * Look for any unwanted ranges between mstart, mend and remove them. This
> - * might lead to split and split ranges are put in cmem->ranges[] array
> - */
> -static int elf_header_exclude_ranges(struct crash_mem *cmem)
> -{
> - int ret = 0;
> - int i;
> -
> - /* Exclude the low 1M because it is always reserved */
> - ret = crash_exclude_mem_range(cmem, 0, SZ_1M - 1);
> - if (ret)
> - return ret;
> -
> - /* Exclude crashkernel region */
> - ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
> - if (ret)
> - return ret;
> -
> - if (crashk_low_res.end)
> - ret = crash_exclude_mem_range(cmem, crashk_low_res.start,
> - crashk_low_res.end);
> - if (ret)
> - return ret;
> -
> - for (i = 0; i < crashk_cma_cnt; ++i) {
> - ret = crash_exclude_mem_range(cmem, crashk_cma_ranges[i].start,
> - crashk_cma_ranges[i].end);
> - if (ret)
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg)
> {
> struct crash_mem *cmem = arg;
> @@ -247,8 +212,8 @@ static int prepare_elf_headers(void **addr, unsigned long *sz,
> if (ret)
> goto out;
>
> - /* Exclude unwanted mem ranges */
> - ret = elf_header_exclude_ranges(cmem);
> + /* Exclude the low 1M because it is always reserved */
> + ret = crash_exclude_mem_range(cmem, 0, SZ_1M - 1);
> if (ret)
> goto out;
>
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 99dac1aa972a..5c0de111ddc3 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -18,6 +18,7 @@
> #include <linux/memblock.h>
> #include <linux/kmemleak.h>
> #include <linux/crash_core.h>
> +#include <linux/crash_reserve.h>
> #include <linux/reboot.h>
> #include <linux/btf.h>
> #include <linux/objtool.h>
> @@ -161,8 +162,30 @@ static inline resource_size_t crash_resource_size(const struct resource *res)
> return !res->end ? 0 : resource_size(res);
> }
>
> +static int crash_exclude_mem_ranges(struct crash_mem *cmem)
> +{
> + int ret, i;
> +
> + /* Exclude crashkernel region */
> + ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
> + if (ret)
> + return ret;
> +
> + if (crashk_low_res.end) {
> + ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
> + if (ret)
> + return ret;
> + }
>
> + for (i = 0; i < crashk_cma_cnt; ++i) {
> + ret = crash_exclude_mem_range(cmem, crashk_cma_ranges[i].start,
> + crashk_cma_ranges[i].end);
> + if (ret)
> + return ret;
> + }
>
> + return ret;
> +}
>
> int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
> void **addr, unsigned long *sz)
> @@ -174,6 +197,11 @@ int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
> unsigned int cpu, i;
> unsigned long long notes_addr;
> unsigned long mstart, mend;
> + int ret;
> +
> + ret = crash_exclude_mem_ranges(mem);
I think the assumption here is that mem should have enough space
to hold the extra ranges created while excluding crash memory ranges.
Right now, this is not happening on powerpc for the case I mentioned
in the above comment.
Also, if crashk_cma_cnt changes in the future, or if a new type of
crash memory is added, then every architecture would need to adjust
the mem allocation accordingly. Instead, could we handle this in
generic code rather than in architecture-specific code, so that we
always ensure mem has enough space?
> + if (ret)
> + return ret;
>
> /* extra phdr for vmcoreinfo ELF note */
> nr_phdr = nr_cpus + 1;
Powered by blists - more mailing lists