2018-04-05 08:58:41 +02:00
|
|
|
From: Hari Bathini <hbathini@linux.vnet.ibm.com>
|
|
|
|
Date: Mon, 26 Mar 2018 14:16:34 +0530
|
2018-04-05 09:13:09 +02:00
|
|
|
Subject: kexec/ppc64: leverage kexec_file_load support
|
|
|
|
References: bsc#1080916
|
|
|
|
Upstream: merged
|
|
|
|
Git-commit: 3720b743ae3ced0407e811a4223228d305dc4705
|
2018-04-05 08:58:41 +02:00
|
|
|
|
|
|
|
PPC64 kernel now supports kexec_file_load system call. Leverage it by
|
|
|
|
enabling that support here. Note that loading crash kernel with this
|
|
|
|
system call is not yet supported in the kernel and trying to load one
|
|
|
|
will fail with '-ENOTSUPP' error.
|
|
|
|
|
|
|
|
Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
|
|
|
|
Reviewed-by: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
|
|
|
|
Signed-off-by: Simon Horman <horms@verge.net.au>
|
|
|
|
---
|
|
|
|
kexec/arch/ppc64/kexec-elf-ppc64.c | 84 ++++++++++++++++++++++++++++++++++++++
|
|
|
|
kexec/kexec-syscall.h | 3 ++
|
|
|
|
2 files changed, 87 insertions(+)
|
|
|
|
|
|
|
|
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
|
|
|
|
index ddd3de8235fd..3510b70821da 100644
|
|
|
|
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
|
|
|
|
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
|
|
|
|
@@ -93,6 +93,85 @@ static int read_prop(char *name, void *value, size_t len)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static int elf_ppc64_load_file(int argc, char **argv, struct kexec_info *info)
|
|
|
|
+{
|
|
|
|
+ int ret = 0;
|
|
|
|
+ char *cmdline, *dtb;
|
|
|
|
+ int opt, cmdline_len = 0;
|
|
|
|
+
|
|
|
|
+ /* See options.h -- add any more there, too. */
|
|
|
|
+ static const struct option options[] = {
|
|
|
|
+ KEXEC_ARCH_OPTIONS
|
|
|
|
+ { "command-line", 1, NULL, OPT_APPEND },
|
|
|
|
+ { "append", 1, NULL, OPT_APPEND },
|
|
|
|
+ { "ramdisk", 1, NULL, OPT_RAMDISK },
|
|
|
|
+ { "initrd", 1, NULL, OPT_RAMDISK },
|
|
|
|
+ { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB },
|
|
|
|
+ { "dtb", 1, NULL, OPT_DEVICETREEBLOB },
|
|
|
|
+ { "args-linux", 0, NULL, OPT_ARGS_IGNORE },
|
|
|
|
+ { 0, 0, NULL, 0 },
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ static const char short_options[] = KEXEC_OPT_STR "";
|
|
|
|
+
|
|
|
|
+ /* Parse command line arguments */
|
|
|
|
+ cmdline = 0;
|
|
|
|
+ dtb = 0;
|
|
|
|
+ ramdisk = 0;
|
|
|
|
+
|
|
|
|
+ while ((opt = getopt_long(argc, argv, short_options,
|
|
|
|
+ options, 0)) != -1) {
|
|
|
|
+ switch (opt) {
|
|
|
|
+ default:
|
|
|
|
+ /* Ignore core options */
|
|
|
|
+ if (opt < OPT_ARCH_MAX)
|
|
|
|
+ break;
|
|
|
|
+ case OPT_APPEND:
|
|
|
|
+ cmdline = optarg;
|
|
|
|
+ break;
|
|
|
|
+ case OPT_RAMDISK:
|
|
|
|
+ ramdisk = optarg;
|
|
|
|
+ break;
|
|
|
|
+ case OPT_DEVICETREEBLOB:
|
|
|
|
+ dtb = optarg;
|
|
|
|
+ break;
|
|
|
|
+ case OPT_ARGS_IGNORE:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (dtb)
|
|
|
|
+ die("--dtb not supported while using --kexec-file-syscall.\n");
|
|
|
|
+
|
|
|
|
+ if (reuse_initrd)
|
|
|
|
+ die("--reuseinitrd not supported with --kexec-file-syscall.\n");
|
|
|
|
+
|
|
|
|
+ if (cmdline) {
|
|
|
|
+ cmdline_len = strlen(cmdline) + 1;
|
|
|
|
+ } else {
|
|
|
|
+ cmdline = strdup("\0");
|
|
|
|
+ cmdline_len = 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ramdisk) {
|
|
|
|
+ info->initrd_fd = open(ramdisk, O_RDONLY);
|
|
|
|
+ if (info->initrd_fd == -1) {
|
|
|
|
+ fprintf(stderr, "Could not open initrd file %s:%s\n",
|
|
|
|
+ ramdisk, strerror(errno));
|
|
|
|
+ ret = -1;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ info->command_line = cmdline;
|
|
|
|
+ info->command_line_len = cmdline_len;
|
|
|
|
+ return ret;
|
|
|
|
+out:
|
|
|
|
+ if (cmdline_len == 1)
|
|
|
|
+ free(cmdline);
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
|
|
|
|
struct kexec_info *info)
|
|
|
|
{
|
|
|
|
@@ -132,6 +211,9 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
|
|
|
|
|
|
|
|
static const char short_options[] = KEXEC_OPT_STR "";
|
|
|
|
|
|
|
|
+ if (info->file_mode)
|
|
|
|
+ return elf_ppc64_load_file(argc, argv, info);
|
|
|
|
+
|
|
|
|
/* Parse command line arguments */
|
|
|
|
initrd_base = 0;
|
|
|
|
initrd_size = 0;
|
|
|
|
@@ -387,6 +469,8 @@ void elf_ppc64_usage(void)
|
|
|
|
fprintf(stderr, " --ramdisk=<filename> Initial RAM disk.\n");
|
|
|
|
fprintf(stderr, " --initrd=<filename> same as --ramdisk.\n");
|
|
|
|
fprintf(stderr, " --devicetreeblob=<filename> Specify device tree blob file.\n");
|
|
|
|
+ fprintf(stderr, " ");
|
|
|
|
+ fprintf(stderr, "Not applicable while using --kexec-file-syscall.\n");
|
|
|
|
fprintf(stderr, " --dtb=<filename> same as --devicetreeblob.\n");
|
|
|
|
|
|
|
|
fprintf(stderr, "elf support is still broken\n");
|
|
|
|
diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
|
|
|
|
index 3b5c528d8aac..33638c25794c 100644
|
|
|
|
--- a/kexec/kexec-syscall.h
|
|
|
|
+++ b/kexec/kexec-syscall.h
|
|
|
|
@@ -61,6 +61,9 @@
|
|
|
|
#ifdef __x86_64__
|
|
|
|
#define __NR_kexec_file_load 320
|
|
|
|
#endif
|
|
|
|
+#ifdef __powerpc64__
|
|
|
|
+#define __NR_kexec_file_load 382
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
#ifndef __NR_kexec_file_load
|
|
|
|
/* system call not available for the arch */
|
|
|
|
--
|
|
|
|
2.13.6
|
|
|
|
|