[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