riscv: kexec_file: Support loading Image binary file
v3 cover riscv: kexec_file: Support loading Image binary file
From: Björn Töpel <[email protected]>
Hi!
For over a year ago, Daniel and I was testing the V2 of Song's series. I also promised to take the V2, that had been sitting on the lists for too long, to rebase it on a new kernel, and re-test it.
One year later, here's the V3! ;-)
There are no changes from V2 other, than some simple checkpatch cleanups.
Song's original cover:
| This series makes the kexec_file_load() syscall support to load | Image binary file. At the same time, corresponding support for | kexec-tools had been pushed to my repo[2]. | | Now, we can leverage that kexec-tools and this series to use the | kexec_load() or kexec_file_load() syscall to boot both vmlinux and | Image file, as seen in these combo tests: | | ``` | 1. kexec -l vmlinux | 2. kexec -l Image | 3. kexec -s -l vmlinux | 4. kexec -s -l Image | ```
Notably, kexec-tools has still not made it upstream. I've prepared a branch on my GH [3], that I indend to post ASAP. That branch is a collection of fixes/features, including Song's userland Image loading.
The V2 is here [2], and V1 [1].
I've tested the kexec-file/Image on qemu-rv64, with following combinations:
* ACPI/UEFI
* DT/UEFI
* DT
both "regular" kexec (-s + -e), and crashkernels (-p).
Note that there are two purgatory patches that has to be present (part of -rc1, so all good):
commit 28093cfef5dd ("riscv/kexec_file: Handle R_RISCV_64 in purgatory relocator") commit 3f7023171df4 ("riscv/purgatory: 4B align purgatory_start")
[1] https://lore.kernel.org/linux-riscv/[email protected]/
[2] https://lore.kernel.org/linux-riscv/[email protected]/
[3] https://github.com/bjoto/kexec-tools/tree/rv-on-master
Song Shuai (2):
riscv: kexec_file: Split the loading of kernel and others
riscv: kexec_file: Support loading Image binary file
arch/riscv/include/asm/image.h | 2 + arch/riscv/include/asm/kexec.h | 6 + arch/riscv/kernel/Makefile | 2 +- arch/riscv/kernel/elf_kexec.c | 485 ------------------------- arch/riscv/kernel/kexec_elf.c | 144 ++++++++ arch/riscv/kernel/kexec_image.c | 96 +++++ arch/riscv/kernel/machine_kexec_file.c | 361 ++++++++++++++++++ 7 files changed, 610 insertions(+), 486 deletions(-) delete mode 100644 arch/riscv/kernel/elf_kexec.c create mode 100644 arch/riscv/kernel/kexec_elf.c create mode 100644 arch/riscv/kernel/kexec_image.c
base-commit: a24588245776dafc227243a01bfbeb8a59bafba9
Signature · 1 line
2.45.2
PATCH v3 1/2 riscv: kexec_file: Split the loading of kernel and others
From: Song Shuai <[email protected]>
This is the preparative patch for kexec_file_load Image support.
It separates the elf_kexec_load() as two parts:
- the first part loads the vmlinux (or Image)
- the second part loads other segments (e.g. initrd,fdt,purgatory)
And the second part is exported as the load_extra_segments() function which would be used in both kexec-elf.c and kexec-image.c.
No functional change intended.
--- arch/riscv/include/asm/kexec.h | 5 + arch/riscv/kernel/Makefile | 2 +- arch/riscv/kernel/elf_kexec.c | 485 ------------------------- arch/riscv/kernel/kexec_elf.c | 144 ++++++++ arch/riscv/kernel/machine_kexec_file.c | 360 ++++++++++++++++++ 5 files changed, 510 insertions(+), 486 deletions(-) delete mode 100644 arch/riscv/kernel/elf_kexec.c create mode 100644 arch/riscv/kernel/kexec_elf.c
arch/riscv/include/asm/kexec.h +5 -0
@@ -67,6 +67,11 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,struct kimage ;int arch_kimage_file_post_load_cleanup (struct kimage *image);#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup + +int load_extra_segments (struct kimage *image,unsigned long kernel_start, +unsigned long kernel_len,char *initrd, +unsigned long initrd_len,char *cmdline, +unsigned long cmdline_len);#endif #endif
arch/riscv/kernel/Makefile +1 -1
@@ -107,7 +107,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o -obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o +obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o machine_kexec_file.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
arch/riscv/kernel/elf_kexec.c deleted +0 -485
485 lines not on this page · raw message
arch/riscv/kernel/kexec_elf.c new file +144 -0
144 lines not on this page · raw message
arch/riscv/kernel/machine_kexec_file.c +360 -0
368 lines not on this page · raw message
Signature · 1 line
2.45.2
PATCH v3 2/2 riscv: kexec_file: Support loading Image binary file
In reply to Björn TöpelFrom: Song Shuai <[email protected]>
This patch creates image_kexec_ops to load Image binary file for kexec_file_load() syscall.
--- arch/riscv/include/asm/image.h | 2 + arch/riscv/include/asm/kexec.h | 1 + arch/riscv/kernel/Makefile | 2 +- arch/riscv/kernel/kexec_image.c | 96 ++++++++++++++++++++++++++ arch/riscv/kernel/machine_kexec_file.c | 1 + 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/kernel/kexec_image.c
arch/riscv/include/asm/image.h +2 -0
@@ -30,6 +30,8 @@ RISCV_HEADER_VERSION_MINOR)#ifndef __ASSEMBLY__ +#define riscv_image_flag_field (flags, field)\ + (((flags) >> field##_SHIFT) & field##_MASK)/** * struct riscv_image_header - riscv kernel image header * @code0: Executable code
arch/riscv/include/asm/kexec.h +1 -0
@@ -56,6 +56,7 @@ extern riscv_kexec_method riscv_kexec_norelocate;#ifdef CONFIG_KEXEC_FILE extern const struct kexec_file_ops elf_kexec_ops; +extern const struct kexec_file_ops image_kexec_ops;struct purgatory_info ; int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
arch/riscv/kernel/Makefile +1 -1
@@ -107,7 +107,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o -obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o machine_kexec_file.o +obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o kexec_image.o machine_kexec_file.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
arch/riscv/kernel/kexec_image.c new file +96 -0
96 lines not on this page · raw message
arch/riscv/kernel/machine_kexec_file.c +1 -0
@@ -18,6 +18,7 @@const struct kexec_file_ops *const kexec_file_loaders[] = { &elf_kexec_ops, + &image_kexec_ops,NULL };
Signature · 1 line
2.45.2
Hi Björn,
Quoted 124 lines · Björn Töpel
From: Song Shuai <[email protected]>
This patch creates
image_kexec_opsto load Image binary file forkexec_file_load()syscall.Signed-off-by Song Shuai <[email protected]>Signed-off-by Björn Töpel <[email protected]>--- arch/riscv/include/asm/image.h | 2 + arch/riscv/include/asm/kexec.h | 1 + arch/riscv/kernel/Makefile | 2 +- arch/riscv/kernel/kexec_image.c | 96 ++++++++++++++++++++++++++ arch/riscv/kernel/machine_kexec_file.c | 1 + 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/kernel/kexec_image.carch/riscv/include/asm/image.h +2
-0@@ -30,6 +30,8 @@ RISCV_HEADER_VERSION_MINOR)#ifndef __ASSEMBLY__ +#define riscv_image_flag_field (flags, field)\ + (((flags) >> field##_SHIFT) & field##_MASK)/** * struct riscv_image_header - riscv kernel image header * @code0: Executable code arch/riscv/include/asm/kexec.h +1
-0@@ -56,6 +56,7 @@ extern riscv_kexec_method riscv_kexec_norelocate;#ifdef CONFIG_KEXEC_FILE extern const struct kexec_file_ops elf_kexec_ops; +extern const struct kexec_file_ops image_kexec_ops;struct purgatory_info ; int arch_kexec_apply_relocations_add(struct purgatory_info *pi,arch/riscv/kernel/Makefile +1
-1@@ -107,7 +107,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o -obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o machine_kexec_file.o +obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o kexec_image.o machine_kexec_file.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_VMCORE_INFO) += vmcore_info.oarch/riscv/kernel/kexec_image.c new file +63
-0@@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* RISC-V Kexec image loader +* +*/ + +#define pr_fmt (fmt) "kexec_file(Image): " fmt + +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/kexec.h> +#include <linux/pe.h> +#include <linux/string.h> +#include <asm/byteorder.h> +#include <asm/image.h> + +static int image_probe (const char *kernel_buf,unsigned long kernel_len) +{ +const struct riscv_image_header *h = (const struct riscv_image_header *)kernel_buf; + +if (!h || kernel_len <sizeof (*h)) +return -EINVAL ; + +/* According to Documentation/riscv/boot-image-header.rst, +* use "magic2" field to check when version >= 0.2. +*/ + +if (h->version >=RISCV_HEADER_VERSION && +memcmp (&h->magic2,RISCV_IMAGE_MAGIC2 ,sizeof (h->magic2))) +return -EINVAL ; + +return 0 ; +} + +static void *image_load (struct kimage *image, +char *kernel,unsigned long kernel_len, +char *initrd,unsigned long initrd_len, +char *cmdline,unsigned long cmdline_len) +{ +struct riscv_image_header *h; +u64 flags; +bool be_image, be_kernel; +struct kexec_buf kbuf; +int ret; + +/* Check Image header */ + h = (struct riscv_image_header *)kernel; +if (!h->image_size) { + ret = -EINVAL ; + goto out; + } + +/* Check endianness */ + flags =le64_to_cpu (h->flags); + be_image =riscv_image_flag_field (flags,RISCV_IMAGE_FLAG_BE ); + be_kernel =IS_ENABLED (CONFIG_CPU_BIG_ENDIAN ); +if (be_image != be_kernel) { + ret = -EINVAL ; + goto out; + } + +/* Load the kernel image */
arch/riscv/kernel/kexec_image.c line 73
Quoted 10 lines
arch/riscv/kernel/kexec_image.c new file +10
-0+ kbuf.image = image; + kbuf.buf_min =0 ; + kbuf.buf_max =ULONG_MAX ; + kbuf.top_down = false; + + kbuf.buffer = kernel; + kbuf.bufsz = kernel_len; + kbuf.mem =KEXEC_BUF_MEM_UNKNOWN ; + kbuf.memsz =le64_to_cpu (h->image_size); + kbuf.buf_align =le64_to_cpu (h->text_offset);
It is necessary to ensure that the kernel entry is aligned to PMD_SIZE; otherwise, BUG_ON() in setup_vm() will be triggered.
Quoted 36 lines
arch/riscv/kernel/kexec_image.c new file +23
-0+ + ret =kexec_add_buffer (&kbuf); +if (ret) { +pr_err ("Error add kernel image ret=%d\n" , ret); + goto out; + } + + image->start = kbuf.mem; + +pr_info ("Loaded kernel at 0x%lx bufsz=0x%lx memsz=0x%lx\n" , + kbuf.mem, kbuf.bufsz, kbuf.memsz); + + ret =load_extra_segments (image, kbuf.mem, kbuf.memsz, + initrd, initrd_len, cmdline, cmdline_len); + +out: +return ret ?ERR_PTR (ret) :NULL ; +} + +const struct kexec_file_ops image_kexec_ops = { + .probe = image_probe, + .load = image_load, +};arch/riscv/kernel/machine_kexec_file.c +1
-1@@ -18,6 +18,7 @@const struct kexec_file_ops *const kexec_file_loaders[] = { &elf_kexec_ops, + &image_kexec_ops,NULL }; --
Quoted 3 lines
2.45.2
Thanks,
Yunhui
Hey Yunhui!
Quoted 3 lines · yunhui cui
Hi Björn,
On Thu, Apr 10, 2025 at 3:31 AM Björn Töpel <[email protected]> wrote:
...
Quoted 8 lines
arch/riscv/kernel/kexec_image.c line 73
Quoted 5 lines
arch/riscv/kernel/kexec_image.c new file +5
-0+ kbuf.buffer = kernel; + kbuf.bufsz = kernel_len; + kbuf.mem =KEXEC_BUF_MEM_UNKNOWN ; + kbuf.memsz =le64_to_cpu (h->image_size); + kbuf.buf_align =le64_to_cpu (h->text_offset);It is necessary to ensure that the kernel entry is aligned to
PMD_SIZE; otherwise,BUG_ON()insetup_vm()will be triggered.
Indeed, and text_offset is that [1]. FWIW, the text_offset name in the Image has always weird/confusing to me.
Björn
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/kernel/head.S#n47
kernel test robot
build botkernel test robot noticed the following build warnings:
Hi Björn,
kernel test robot noticed the following build warnings:
[auto build test WARNING on a24588245776dafc227243a01bfbeb8a59bafba9]
url: https://github.com/intel-lab-lkp/linux/commits/Bj-rn-T-pel/riscv-kexec_file-Split-the-loading-of-kernel-and-others/20250410-033243 base: a24588245776dafc227243a01bfbeb8a59bafba9 patch link: https://lore.kernel.org/r/20250409193004.643839-3-bjorn%40kernel.org patch subject: [PATCH v3 2/2] riscv: kexec_file: Support loading Image binary file reproduce: (https://download.01.org/0day-ci/archive/20250416/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
Warning: Documentation/translations/zh_CN/admin-guide/README.rst references a file that doesn't exist: Documentation/dev-tools/kgdb.rst
Warning: Documentation/translations/zh_CN/dev-tools/gdb-kernel-debugging.rst references a file that doesn't exist: Documentation/dev-tools/gdb-kernel-debugging.rst
Warning: Documentation/translations/zh_TW/admin-guide/README.rst references a file that doesn't exist: Documentation/dev-tools/kgdb.rst
Warning: Documentation/translations/zh_TW/dev-tools/gdb-kernel-debugging.rst references a file that doesn't exist: Documentation/dev-tools/gdb-kernel-debugging.rst
Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/leds/backlight/ti,lp8864.yaml
>> Warning: arch/riscv/kernel/kexec_image.c references a file that doesn't exist: Documentation/riscv/boot-image-header.rst
Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 984. make[2]: *** [Documentation/Makefile:121: htmldocs] Error 255
make[1]: *** [Makefile:1804: htmldocs] Error 2
make: *** [Makefile:248: __sub-make] Error 2
make: Target 'htmldocs' not remade because of errors.
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
This series was applied to riscv/linux.git (for-next) by Alexandre Ghiti <[email protected]>:
Hello:
This series was applied to riscv/linux.git (for-next) by Alexandre Ghiti <[email protected]>:
Quoted 9 lines · On Wed, 9 Apr 2025 21:29:57 +0200 you wrote:
From: Björn Töpel <[email protected]>
Hi!
For over a year ago, Daniel and I was testing the V2 of Song's series. I also promised to take the V2, that had been sitting on the lists for too long, to rebase it on a new kernel, and re-test it.
[...]
Here is the summary with links:
- [v3,1/2] riscv: kexec_file: Split the loading of kernel and others
https://git.kernel.org/riscv/c/4abec7d96c18 - [v3,2/2] riscv: kexec_file: Support loading Image binary file https://git.kernel.org/riscv/c/1d57a3df656f
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html