[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