From: Li Zhengyu <lizhengyu3@xxxxxxxxxx> Create prepare_kexec_file_options() function to prepare the options to kexec_file_load syscall, and it would be used in elf_riscv_load() or the future image_riscv_load(). The patch comes from the RISC-V Linux kernel_file_load support[1], So its author should be Li Zhengyu. [1]: https://lore.kernel.org/all/20220408100914.150110-1-lizhengyu3@xxxxxxxxxx/ Signed-off-by: Song Shuai <songshuaishuai@xxxxxxxxxxx> --- kexec/arch/riscv/kexec-elf-riscv.c | 5 ++-- kexec/arch/riscv/kexec-riscv.c | 41 ++++++++++++++++++++++++++++++ kexec/arch/riscv/kexec-riscv.h | 1 + kexec/kexec-syscall.h | 3 +++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/kexec/arch/riscv/kexec-elf-riscv.c b/kexec/arch/riscv/kexec-elf-riscv.c index f3c011c..2b9f66d 100644 --- a/kexec/arch/riscv/kexec-elf-riscv.c +++ b/kexec/arch/riscv/kexec-elf-riscv.c @@ -112,6 +112,7 @@ void elf_riscv_usage(void) { } + int elf_riscv_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { @@ -127,9 +128,7 @@ int elf_riscv_load(int argc, char **argv, const char *buf, off_t len, int ret = 0; if (info->file_mode) { - fprintf(stderr, "kexec_file not supported on this " - "architecture\n"); - return -EINVAL; + return prepare_kexec_file_options(info); } /* Parse the ELF file */ diff --git a/kexec/arch/riscv/kexec-riscv.c b/kexec/arch/riscv/kexec-riscv.c index 00ae869..4500aa9 100644 --- a/kexec/arch/riscv/kexec-riscv.c +++ b/kexec/arch/riscv/kexec-riscv.c @@ -16,6 +16,14 @@ #include <libfdt.h> /* For DeviceTree handling */ #include "kexec-riscv.h" #include "iomem.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#ifndef _O_BINARY +#define _O_BINARY 0 +#endif + + const struct arch_map_entry arches[] = { { "riscv32", KEXEC_ARCH_RISCV }, @@ -141,6 +149,39 @@ void arch_usage(void) printf(riscv_opts_usage); } +int prepare_kexec_file_options(struct kexec_info *info) +{ + int fd; + ssize_t result; + struct stat stats; + + if (arch_options.cmdline) { + info->command_line = (char *)arch_options.cmdline; + info->command_line_len = strlen(info->command_line) + 1; + } + + if (!arch_options.initrd_path) { + info->initrd_fd = -1; + return 0; + } + + fd = open(arch_options.initrd_path, O_RDONLY | _O_BINARY); + if (fd < 0) { + fprintf(stderr, "Cannot open `%s': %s\n", arch_options.initrd_path, + strerror(errno)); + return -EINVAL; + } + result = fstat(fd, &stats); + if (result < 0) { + close(fd); + fprintf(stderr, "Cannot stat: %s: %s\n", arch_options.initrd_path, + strerror(errno)); + return -EINVAL; + } + info->initrd_fd = fd; + return 0; +} + int arch_process_options(int argc, char **argv) { static const struct option options[] = { diff --git a/kexec/arch/riscv/kexec-riscv.h b/kexec/arch/riscv/kexec-riscv.h index c4323a6..f136c7e 100644 --- a/kexec/arch/riscv/kexec-riscv.h +++ b/kexec/arch/riscv/kexec-riscv.h @@ -23,6 +23,7 @@ extern struct memory_range elfcorehdr_mem; int load_elfcorehdr(struct kexec_info *info); /* kexec-riscv.c */ +int prepare_kexec_file_options(struct kexec_info *info); int load_extra_segments(struct kexec_info *info, uint64_t kernel_base, uint64_t kernel_size, uint64_t max_addr); diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h index 4cdae84..2310b98 100644 --- a/kexec/kexec-syscall.h +++ b/kexec/kexec-syscall.h @@ -80,6 +80,9 @@ #ifdef __hppa__ #define __NR_kexec_file_load 355 #endif +#if defined(__riscv__) || defined(__riscv) +#define __NR_kexec_file_load 294 +#endif #ifndef __NR_kexec_file_load /* system call not available for the arch */ -- 2.20.1 _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec