[PATCH 4/7] LoongArch: Enforce relocatable kernel check for crash dump
Youling Tang
youling.tang at linux.dev
Fri Aug 29 02:10:37 PDT 2025
From: Youling Tang <tangyouling at kylinios.cn>
Without enabling the RELOCATABLE configuration, LoongArch is a non-PIE kernel
and cannot be loaded to run at any appropriate address. So the CRASH_DUMP
feature depends on RELOCATABLE.
$ cat arch/loongarch/Kconfig
config ARCH_SELECTS_CRASH_DUMP
def_bool y
depends on CRASH_DUMP
select RELOCATABLE
The relocatable kernel is determined by checking if there is a la_abs section.
Currently, only the elf format has been checked, while pei/pez is in the FIXME
state.
Signed-off-by: Youling Tang <tangyouling at kylinios.cn>
---
kexec/arch/loongarch/kexec-elf-loongarch.c | 32 ++++++++++++++++++++++
kexec/arch/loongarch/kexec-pei-loongarch.c | 3 ++
2 files changed, 35 insertions(+)
diff --git a/kexec/arch/loongarch/kexec-elf-loongarch.c b/kexec/arch/loongarch/kexec-elf-loongarch.c
index c87f022..44b63a9 100644
--- a/kexec/arch/loongarch/kexec-elf-loongarch.c
+++ b/kexec/arch/loongarch/kexec-elf-loongarch.c
@@ -13,6 +13,7 @@
#include <limits.h>
#include <errno.h>
#include <elf.h>
+#include <stdbool.h>
#include "kexec.h"
#include "kexec-elf.h"
@@ -47,6 +48,27 @@ out:
return result;
}
+/*
+ * To determine whether it is a relocatable kernel based on the ".la_abs "section,
+ * the CRASH_DUMP feature depends on CONFIG_RELOCATABLE in LoongArch.
+ */
+static bool laabs_section(const struct mem_ehdr *ehdr)
+{
+ struct mem_shdr *shdr, *shdr_end;
+ unsigned char *strtab;
+
+ strtab = (unsigned char *)ehdr->e_shdr[ehdr->e_shstrndx].sh_data;
+ shdr_end = &ehdr->e_shdr[ehdr->e_shnum];
+ for (shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) {
+ if (shdr->sh_size &&
+ strcmp((char *)&strtab[shdr->sh_name], ".la_abs") == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
int elf_loongarch_load(int argc, char **argv, const char *kernel_buf,
off_t kernel_size, struct kexec_info *info)
{
@@ -63,6 +85,16 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf,
goto exit;
}
+ if (info->kexec_flags & KEXEC_ON_CRASH) {
+ bool is_relocatable_kernel = laabs_section(&ehdr);
+ if (!is_relocatable_kernel) {
+ dbgprintf("%s: The non-relocation kernel cannot be loaded, "
+ "CONFIG_RELOCATABLE needs to be enabled\n", __func__);
+ result = EFAILED;
+ goto exit;
+ }
+ }
+
/* Find and process the loongarch image header. */
for (i = 0; i < ehdr.e_phnum; i++) {
struct mem_phdr *phdr = &ehdr.e_phdr[i];
diff --git a/kexec/arch/loongarch/kexec-pei-loongarch.c b/kexec/arch/loongarch/kexec-pei-loongarch.c
index f0e0d09..1a19a39 100644
--- a/kexec/arch/loongarch/kexec-pei-loongarch.c
+++ b/kexec/arch/loongarch/kexec-pei-loongarch.c
@@ -99,6 +99,9 @@ int pei_loongarch_load(int argc, char **argv, const char *buf,
}
}
+ /* Fixme: Loading a non-relocation kernel will cause the second kernel to fail
+ to start in KEXEC_ON_CRASH */
+
/* Load the kernel */
add_segment(info, buf, len, kernel_segment, loongarch_mem.image_size);
--
2.34.1
More information about the kexec
mailing list