From: Youling Tang <tangyoul...@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 <tangyoul...@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


Reply via email to