From: Jinjie Ruan <ruanjinjie@huawei.com>
To: Mike Rapoport <rppt@kernel.org>
Cc: <catalin.marinas@arm.com>, <will@kernel.org>,
<mark.rutland@arm.com>, <chenhuacai@kernel.org>,
<kernel@xen0n.name>, <maddy@linux.ibm.com>, <mpe@ellerman.id.au>,
<npiggin@gmail.com>, <chleroy@kernel.org>,
<ritesh.list@gmail.com>, <sshegde@linux.ibm.com>,
<pjw@kernel.org>, <palmer@dabbelt.com>, <aou@eecs.berkeley.edu>,
<alex@ghiti.fr>, <tglx@kernel.org>, <mingo@redhat.com>,
<bp@alien8.de>, <dave.hansen@linux.intel.com>, <hpa@zytor.com>,
<akpm@linux-foundation.org>, <baoquan.he@linux.dev>,
<pasha.tatashin@soleen.com>, <pratyush@kernel.org>,
<thuth@redhat.com>, <leitao@debian.org>, <yeoreum.yun@arm.com>,
<robh@kernel.org>, <sourabhjain@linux.ibm.com>, <kees@kernel.org>,
<coiby.xu@gmail.com>, <Yeking@Red54.com>,
<tangyouling@kylinos.cn>, <maqianga@uniontech.com>,
<zhangtianyang@loongson.cn>, <guodongtai@kylinos.cn>,
<blum@kernel.org>, <adityag@linux.ibm.com>,
<hui.wang@canonical.com>, <sohammetha01@gmail.com>,
<guoren@kernel.org>, <gaohan@iscas.ac.cn>, <kai.huang@intel.com>,
<kas@kernel.org>, <vishal.l.verma@intel.com>, <piliu@redhat.com>,
<jbouron@amazon.com>, <mclapinski@google.com>, <me@linux.beauty>,
<graf@amazon.com>, <bgwin@google.com>, <x86@kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <loongarch@lists.linux.dev>,
<linuxppc-dev@lists.ozlabs.org>,
<linux-riscv@lists.infradead.org>, <kexec@lists.infradead.org>
Subject: Re: [PATCH v7 12/15] kexec: Add kexec_load_other_segments() helper
Date: Wed, 11 Nov 2026 20:01:59 +0800 [thread overview]
Message-ID: <d6047caf-4838-4007-8483-8739dd2a429a@huawei.com> (raw)
In-Reply-To: <179430504583.425130.15302016434972990362.b4-review@b4>
在 2026/11/10 18:04, Mike Rapoport 写道:
> Hi Jinjie,
Hi Mike,
>
>> arm64, LoongArch and RISC-V duplicate the elf core header and initrd
>> loading. Move it into a common helper with one arch hook for the boot
>> parameters; a failure releases everything added for the attempt.
>
> I like the idea of pulling out the common code, but I'm not convinced
Thank you for the review.
> that the split you suggest is right.
Yes, the current solution is straightforward.
>
>> Cc: Andrew Morton <akpm@linux-foundation.org>
>> Cc: Baoquan He <baoquan.he@linux.dev>
>> Cc: Mike Rapoport <rppt@kernel.org>
>> Suggested-by: Mike Rapoport <rppt@kernel.org>
>> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
>> ---
>> include/linux/kexec.h | 15 ++++++++
>> kernel/kexec_file.c | 90 +++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 105 insertions(+)
>>
>> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
>> index faba26f871a4a..de1d83ddc38bd 100644
>> --- a/include/linux/kexec.h
>> +++ b/include/linux/kexec.h
>> @@ -259,6 +259,21 @@ int kexec_kernel_verify_pe_sig(const char *kernel, unsigned long kernel_len);
>> extern int kexec_add_buffer(struct kexec_buf *kbuf);
>> int kexec_locate_mem_hole(struct kexec_buf *kbuf);
>>
>> +struct kexec_load_params {
>> + unsigned long kernel_load_addr;
>> + unsigned long kernel_size;
>> + char *initrd;
>> + unsigned long initrd_len;
>> + char *cmdline;
>> + unsigned long cmdline_len;
>> +};
>
> initrd and cmdline are already in image->initrd_buf, initrd_buf_len,
> cmdline_buf and cmdline_buf_len, that's where fops->load() gets them from.
OK, will delete them.
>
> And the outputs are scattered: elf_load_addr goes to the image, the initrd
> address is passed as a separate argument to the hook, and LoongArch infers
> "there is an initrd" from initrd_load_addr != 0.
These are currently just being shoehorned in.
>
>
>
>> +
>> +int arch_kexec_setup_other_segments(struct kimage *image,
>> + struct kexec_load_params *params,
>> + unsigned long initrd_load_addr);
>> +int kexec_load_other_segments(struct kimage *image,
>> + struct kexec_load_params *params, bool top_down);
>> +
>
> The call chain is now fops->load() in arch -> kexec_load_other_segments()
> in core -> arch_kexec_setup_other_segments() back in arch. That's a
> midlayer: the core helper owns the sequence and the arch fills a hole in
> the middle of it.
The new refactoring will follow this principle to ensure that the
framework code is in control of the order.
>
> The weak default is never used, all three users override it, and x86,
> powerpc and s390 build a helper and a hook that nothing calls.
Yes, x86 and powerpc has not used it, Some adjustments need for the rework.
>
>> #ifndef arch_kexec_locate_mem_hole
>> /**
>> * arch_kexec_locate_mem_hole - Find free memory to place the segments.
>> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
>> index 62d4cba278a57..8b80f1186875b 100644
>> --- a/kernel/kexec_file.c
>> +++ b/kernel/kexec_file.c
>> @@ -1295,3 +1295,93 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
>> return 0;
>> }
>> #endif /* CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY */
>> +
>> +int __weak arch_kexec_setup_other_segments(struct kimage *image,
>> + struct kexec_load_params *params,
>> + unsigned long initrd_load_addr)
>> +{
>> + return 0;
>> +}
>> +
>> +int kexec_load_other_segments(struct kimage *image,
>> + struct kexec_load_params *params, bool top_down)
>> +{
>> + struct kexec_buf kbuf = {
>> + .image = image,
>> + /* Do not allocate anything below the kernel */
>> + .buf_min = params->kernel_load_addr + params->kernel_size,
>> + .buf_max = top_down ? PFN_PHYS(max_low_pfn) : ULONG_MAX,
>> + };
>
> top_down does not describe a direction, it selects "RISC-V policy" vs
> "arm64 policy": the upper limit for all buffers, the initrd direction and
> the 32G initrd window.
Yes its the topdown of initrd and distinguish between different
architectures is a bit of a stretch here.
Right! arm64 has its unique boot protocol restrictions. Here, RISC-V has
a bug fix that requires specifying a memory top limit.
>
> These are boot protocol constraints and they belong to the architecture.
Agree
> The 32G window comes from arm64 booting.rst and the SZ_64K alignment below
> is "largest supported page size" on arm64 and LoongArch. With this patch
Yes.
> they become generic and RISC-V silently switches from
> ELF_CORE_HEADER_ALIGN to 64K in 15/15.
There are indeed some function changes, which are also mentioned
in the commit message.
>
>
>> +
>> + unsigned long orig_segments = image->nr_segments;
>> + unsigned long initrd_load_addr = 0;
>> + int ret = 0;
>> +
>> +#ifdef CONFIG_CRASH_DUMP
>> + if (image->type == KEXEC_TYPE_CRASH) {
>> + ret = crash_prepare_headers(true, &kbuf.buffer, &kbuf.bufsz, NULL);
>> + if (ret) {
>> + pr_err("Preparing elf core header failed\n");
>> + goto out_err;
>> + }
>> +
>> + if (unlikely(image->elf_headers))
>> + vfree(image->elf_headers);
>
> The headers don't depend on where the kernel is placed, yet they are
> rebuilt on every iteration of the arm64 and LoongArch retry loops. That's
> why the vfree() above is needed, and with the out_err path freeing them
> it's now dead code.
Yes, it need deleted now.
>
> Building the headers once and only placing them in the loop removes the
> leak instead of fixing it.
I agree, I had a similar fix attempt before, where I only allocated once
to avoid placing it in a loop.
>
>
>> +
>> + image->elf_headers = kbuf.buffer;
>> + image->elf_headers_sz = kbuf.bufsz;
>> +
>> + kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
>> + kbuf.memsz = kbuf.bufsz;
>> + kbuf.buf_align = SZ_64K; /* largest supported page size */
>> + kbuf.top_down = true;
>> +
>> + ret = kexec_add_buffer(&kbuf);
>> + if (ret)
>> + goto out_err;
>> +
>> + image->elf_load_addr = kbuf.mem;
>> +
>> + kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
>> + image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
>> + }
>> +#endif
>> +
>> + if (params->initrd) {
>> + kbuf.buffer = params->initrd;
>> + kbuf.bufsz = params->initrd_len;
>> + kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
>> + kbuf.memsz = params->initrd_len;
>> + kbuf.buf_align = 0;
>> + /* within 1GB-aligned window of up to 32GB in size */
>> + if (!top_down)
>> + kbuf.buf_max = round_down(params->kernel_load_addr, SZ_1G) +
>> + (unsigned long)SZ_1G * 32;
>> + kbuf.top_down = top_down;
>> +
>> + ret = kexec_add_buffer(&kbuf);
>> + if (ret)
>> + goto out_err;
>> + initrd_load_addr = kbuf.mem;
>> +
>> + kexec_dprintk("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
>> + initrd_load_addr, kbuf.bufsz, kbuf.memsz);
>> + }
>> +
>> + ret = arch_kexec_setup_other_segments(image, params,
>> + initrd_load_addr);
>> + if (ret)
>> + goto out_err;
>> +
>> + return 0;
>> +
>> +out_err:
>> + while (image->nr_segments > orig_segments) {
>> + kexec_free_segment_cma(image, image->nr_segments - 1);
>> + image->nr_segments--;
>> + }
>> +
>> + kexec_free_elf_headers(image);
>
> This drops segments added by the arch hook (DTB, RISC-V purgatory, arm64
> dm-crypt keys) without knowing anything about the state attached to them,
> like image->dm_crypt_keys_addr or the purgatory info. The hook, in turn,
> frees its buffers but not its segments.
Yes
>
> Nobody owns the unwind, so "a failure releases everything added for the
> attempt" is not quite what happens.
>
> The conversions also bury ordering changes in "simplify" patches: on arm64
> dm-crypt keys move after the initrd, and on RISC-V the initrd moves before
> the purgatory. And dm-crypt keys loading is not an arm64 boot parameter,
> x86 and powerpc use it as well.
>
Yes, the segment allocation order is indeed changed.
>> +
>> + return ret;
>> +}
>
>
> What I had in mind was to make the core provide building blocks and let
> the architectures compose them, e.g. a common rollback function that
> frees CMAs and drops segments above nr. The retry loops in arm64 and
> LoongArch image loaders can use it instead of open coding
> kexec_free_segment_cma() and nr_segments--. There also could be a helper
I agree.
> for adding FDT for example and maybe some other common parts, like, say,
> efl headers.
I am trying out your refactoring ideas so that x86 and PowerPC can also
use these newly added small hook functions.
>
> Arch's load_other_segments() could use these helpers and still define
> their own policy for segment placement.
This will eliminate the issue of changes in the above sequence or the
problem of the startup protocol being modified.
Thank you again for your review and suggestions for refactoring. I will
thoroughly consider the issues you raised, revise the code, and conduct
more testing.
>
--
Best regards,
Jinjie
next prev parent reply other threads:[~2026-11-11 12:02 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 7:51 [PATCH v7 00/15] kexec: Fix CMA and elf header leaks and rework Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 01/15] arm64: kexec_file: Stop using the Image text_offset Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 02/15] kexec: Extract kexec_free_segment_cma() from kimage_free_cma() Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 03/15] arm64: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
2026-11-03 9:15 ` Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 04/15] arm64: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 05/15] LoongArch: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
2026-11-03 9:16 ` Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 06/15] LoongArch: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 07/15] LoongArch: kexec_file: Fix a modified_cmdline leak Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 08/15] arm64: kexec_file: Simplify load_other_segments() Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 09/15] LoongArch: " Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 10/15] riscv: kexec_file: Simplify load_extra_segments() Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 11/15] kexec: Free the elf core header in kimage_file_post_load_cleanup() Jinjie Ruan
2026-10-26 7:51 ` [PATCH v7 12/15] kexec: Add kexec_load_other_segments() helper Jinjie Ruan
2026-11-10 10:04 ` Mike Rapoport
2026-11-11 12:01 ` Jinjie Ruan [this message]
2026-10-26 7:51 ` [PATCH v7 13/15] arm64: kexec_file: Use kexec_load_other_segments() to simplify code Jinjie Ruan
2026-10-26 7:52 ` [PATCH v7 14/15] LoongArch: " Jinjie Ruan
2026-10-26 7:52 ` [PATCH v7 15/15] riscv: " Jinjie Ruan
2026-11-03 9:14 ` [PATCH v7 00/15] kexec: Fix CMA and elf header leaks and rework Jinjie Ruan
2026-11-04 14:56 ` Mike Rapoport
2026-11-05 3:45 ` Jinjie Ruan
2026-11-05 7:52 ` Mike Rapoport
2026-11-05 8:04 ` Jinjie Ruan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d6047caf-4838-4007-8483-8739dd2a429a@huawei.com \
--to=ruanjinjie@huawei.com \
--cc=Yeking@Red54.com \
--cc=adityag@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=baoquan.he@linux.dev \
--cc=bgwin@google.com \
--cc=blum@kernel.org \
--cc=bp@alien8.de \
--cc=catalin.marinas@arm.com \
--cc=chenhuacai@kernel.org \
--cc=chleroy@kernel.org \
--cc=coiby.xu@gmail.com \
--cc=dave.hansen@linux.intel.com \
--cc=gaohan@iscas.ac.cn \
--cc=graf@amazon.com \
--cc=guodongtai@kylinos.cn \
--cc=guoren@kernel.org \
--cc=hpa@zytor.com \
--cc=hui.wang@canonical.com \
--cc=jbouron@amazon.com \
--cc=kai.huang@intel.com \
--cc=kas@kernel.org \
--cc=kees@kernel.org \
--cc=kernel@xen0n.name \
--cc=kexec@lists.infradead.org \
--cc=leitao@debian.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=loongarch@lists.linux.dev \
--cc=maddy@linux.ibm.com \
--cc=maqianga@uniontech.com \
--cc=mark.rutland@arm.com \
--cc=mclapinski@google.com \
--cc=me@linux.beauty \
--cc=mingo@redhat.com \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
--cc=palmer@dabbelt.com \
--cc=pasha.tatashin@soleen.com \
--cc=piliu@redhat.com \
--cc=pjw@kernel.org \
--cc=pratyush@kernel.org \
--cc=ritesh.list@gmail.com \
--cc=robh@kernel.org \
--cc=rppt@kernel.org \
--cc=sohammetha01@gmail.com \
--cc=sourabhjain@linux.ibm.com \
--cc=sshegde@linux.ibm.com \
--cc=tangyouling@kylinos.cn \
--cc=tglx@kernel.org \
--cc=thuth@redhat.com \
--cc=vishal.l.verma@intel.com \
--cc=will@kernel.org \
--cc=x86@kernel.org \
--cc=yeoreum.yun@arm.com \
--cc=zhangtianyang@loongson.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®