[PATCH 5/7] RISC-V: Enable kexe_file_load
Song Shuai
songshuaishuai at tinylab.org
Thu Sep 14 20:50:11 PDT 2023
From: Li Zhengyu <lizhengyu3 at huawei.com>
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@huawei.com/
Signed-off-by: Song Shuai <songshuaishuai at tinylab.org>
---
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
More information about the kexec
mailing list