[PATCH v2 09/10] LoongArch: Add kexec_file_load syscall
Youling Tang
youling.tang at linux.dev
Mon Sep 15 18:46:54 PDT 2025
From: Youling Tang <tangyouling at kylinos.cn>
Create prepare_kexec_file_options() function to prepare the options
to kexec_file_load syscall, and it would be used in pei_loongarch_load().
Currently, pez(vmlinuz.efi), pei(vmlinux.efi) and elf(vmlinux) format
images are supported.
Signed-off-by: Youling Tang <tangyouling at kylinos.cn>
---
kexec/arch/loongarch/kexec-elf-loongarch.c | 3 ++
kexec/arch/loongarch/kexec-loongarch.c | 39 ++++++++++++++++++++++
kexec/arch/loongarch/kexec-loongarch.h | 1 +
kexec/arch/loongarch/kexec-pei-loongarch.c | 3 ++
kexec/kexec-syscall.h | 5 ++-
5 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/kexec/arch/loongarch/kexec-elf-loongarch.c b/kexec/arch/loongarch/kexec-elf-loongarch.c
index 92fa9f8..1cc6212 100644
--- a/kexec/arch/loongarch/kexec-elf-loongarch.c
+++ b/kexec/arch/loongarch/kexec-elf-loongarch.c
@@ -77,6 +77,9 @@ int elf_loongarch_load(int argc, char **argv, const char *kernel_buf,
int result;
int i;
+ if (info->file_mode)
+ return prepare_kexec_file_options(info);
+
result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0);
if (result < 0) {
diff --git a/kexec/arch/loongarch/kexec-loongarch.c b/kexec/arch/loongarch/kexec-loongarch.c
index 32cd484..eb60ef0 100644
--- a/kexec/arch/loongarch/kexec-loongarch.c
+++ b/kexec/arch/loongarch/kexec-loongarch.c
@@ -10,12 +10,14 @@
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <getopt.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
#include <sys/stat.h>
#include <linux/elf-em.h>
#include <elf.h>
@@ -29,6 +31,10 @@
#include "mem_regions.h"
#include "arch/options.h"
+#ifndef _O_BINARY
+#define _O_BINARY 0
+#endif
+
#define CMDLINE_PREFIX "kexec "
static char cmdline[COMMAND_LINE_SIZE] = CMDLINE_PREFIX;
@@ -201,6 +207,39 @@ struct arch_options_t arch_options = {
.core_header_type = CORE_TYPE_ELF64,
};
+int prepare_kexec_file_options(struct kexec_info *info)
+{
+ int fd;
+ ssize_t result;
+ struct stat stats;
+
+ if (arch_options.command_line) {
+ info->command_line = (char *)arch_options.command_line;
+ info->command_line_len = strlen(info->command_line) + 1;
+ }
+
+ if (!arch_options.initrd_file) {
+ info->initrd_fd = -1;
+ return 0;
+ }
+
+ fd = open(arch_options.initrd_file, O_RDONLY | _O_BINARY);
+ if (fd < 0) {
+ fprintf(stderr, "Cannot open `%s': %s\n", arch_options.initrd_file,
+ strerror(errno));
+ return -EINVAL;
+ }
+ result = fstat(fd, &stats);
+ if (result < 0) {
+ close(fd);
+ fprintf(stderr, "Cannot stat: %s: %s\n", arch_options.initrd_file,
+ strerror(errno));
+ return -EINVAL;
+ }
+ info->initrd_fd = fd;
+ return 0;
+}
+
int arch_process_options(int argc, char **argv)
{
static const char short_options[] = KEXEC_ARCH_OPT_STR "";
diff --git a/kexec/arch/loongarch/kexec-loongarch.h b/kexec/arch/loongarch/kexec-loongarch.h
index 2c7624f..2bffa47 100644
--- a/kexec/arch/loongarch/kexec-loongarch.h
+++ b/kexec/arch/loongarch/kexec-loongarch.h
@@ -37,6 +37,7 @@ int loongarch_process_image_header(const struct loongarch_image_header *h);
unsigned long loongarch_locate_kernel_segment(struct kexec_info *info);
int loongarch_load_other_segments(struct kexec_info *info,
unsigned long hole_min);
+int prepare_kexec_file_options(struct kexec_info *info);
struct arch_options_t {
char *command_line;
diff --git a/kexec/arch/loongarch/kexec-pei-loongarch.c b/kexec/arch/loongarch/kexec-pei-loongarch.c
index e0a82b6..10f79c1 100644
--- a/kexec/arch/loongarch/kexec-pei-loongarch.c
+++ b/kexec/arch/loongarch/kexec-pei-loongarch.c
@@ -70,6 +70,9 @@ int pei_loongarch_load(int argc, char **argv, const char *buf,
header = (const struct loongarch_image_header *)(buf);
+ if (info->file_mode)
+ return prepare_kexec_file_options(info);
+
if (loongarch_process_image_header(header))
return EFAILED;
diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
index 9b17578..e9bb7de 100644
--- a/kexec/kexec-syscall.h
+++ b/kexec/kexec-syscall.h
@@ -59,7 +59,7 @@
#endif
#endif /*ifndef __NR_kexec_load*/
-#if defined(__arm__) || defined(__loongarch__)
+#if defined(__arm__)
#undef __NR_kexec_file_load
#endif
@@ -83,6 +83,9 @@
#if defined(__riscv__) || defined(__riscv)
#define __NR_kexec_file_load 294
#endif
+#ifdef __loongarch__
+#define __NR_kexec_file_load 294
+#endif
#ifndef __NR_kexec_file_load
/* system call not available for the arch */
--
2.34.1
More information about the kexec
mailing list