Blob Blame History Raw
From e63fefd4fc355f29d839ca47484b0f8070e38ccb Mon Sep 17 00:00:00 2001
From: Sourabh Jain <sourabhjain@linux.ibm.com>
Date: Wed, 1 Feb 2023 14:23:31 +0530
Subject: [PATCH 1/6] ppc64: add --reuse-cmdline parameter support

An option to copy the command line arguments from running kernel
to kexec'd kernel. This option works for both kexec and kdump.

In case --append=<args> or --command-line=<args> is provided along
with --reuse-cmdline parameter then args listed against append and
command-line parameter will be combined with command line argument
from running kernel.

Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Signed-off-by: Simon Horman <horms@kernel.org>
---
 kexec/arch/ppc64/include/arch/options.h |  4 +++-
 kexec/arch/ppc64/kexec-elf-ppc64.c      | 25 +++++++++++++++++++++++--
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/kexec/arch/ppc64/include/arch/options.h b/kexec/arch/ppc64/include/arch/options.h
index 71632ec..2bca96a 100644
--- a/kexec/arch/ppc64/include/arch/options.h
+++ b/kexec/arch/ppc64/include/arch/options.h
@@ -10,6 +10,7 @@
 #define OPT_RAMDISK		(OPT_ARCH_MAX+1)
 #define OPT_DEVICETREEBLOB	(OPT_ARCH_MAX+2)
 #define OPT_ARGS_IGNORE		(OPT_ARCH_MAX+3)
+#define OPT_REUSE_CMDLINE	(OPT_ARCH_MAX+4)
 
 /* Options relevant to the architecture (excluding loader-specific ones): */
 #define KEXEC_ARCH_OPTIONS \
@@ -41,7 +42,8 @@
 	{ "initrd",             1, NULL, OPT_RAMDISK },		\
 	{ "devicetreeblob",     1, NULL, OPT_DEVICETREEBLOB },	\
 	{ "dtb",                1, NULL, OPT_DEVICETREEBLOB },	\
-	{ "args-linux",         0, NULL, OPT_ARGS_IGNORE },
+	{ "args-linux",         0, NULL, OPT_ARGS_IGNORE },	\
+	{ "reuse-cmdline",      0, NULL, OPT_REUSE_CMDLINE },
 
 #define KEXEC_ALL_OPT_STR KEXEC_OPT_STR
 
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
index 695b8b0..01d045f 100644
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
@@ -95,6 +95,8 @@ static int elf_ppc64_load_file(int argc, char **argv, struct kexec_info *info)
 {
 	int ret = 0;
 	char *cmdline, *dtb;
+	char *append_cmdline = NULL;
+	char *reuse_cmdline = NULL;
 	int opt, cmdline_len = 0;
 
 	/* See options.h -- add any more there, too. */
@@ -107,6 +109,7 @@ static int elf_ppc64_load_file(int argc, char **argv, struct kexec_info *info)
 		{ "devicetreeblob",     1, NULL, OPT_DEVICETREEBLOB },
 		{ "dtb",                1, NULL, OPT_DEVICETREEBLOB },
 		{ "args-linux",		0, NULL, OPT_ARGS_IGNORE },
+		{ "reuse-cmdline",	0, NULL, OPT_REUSE_CMDLINE},
 		{ 0,                    0, NULL, 0 },
 	};
 
@@ -125,7 +128,7 @@ static int elf_ppc64_load_file(int argc, char **argv, struct kexec_info *info)
 			if (opt < OPT_ARCH_MAX)
 				break;
 		case OPT_APPEND:
-			cmdline = optarg;
+			append_cmdline = optarg;
 			break;
 		case OPT_RAMDISK:
 			ramdisk = optarg;
@@ -135,6 +138,9 @@ static int elf_ppc64_load_file(int argc, char **argv, struct kexec_info *info)
 			break;
 		case OPT_ARGS_IGNORE:
 			break;
+		case OPT_REUSE_CMDLINE:
+			reuse_cmdline = get_command_line();
+			break;
 		}
 	}
 
@@ -144,6 +150,10 @@ static int elf_ppc64_load_file(int argc, char **argv, struct kexec_info *info)
 	if (reuse_initrd)
 		die("--reuseinitrd not supported with --kexec-file-syscall.\n");
 
+	cmdline = concat_cmdline(reuse_cmdline, append_cmdline);
+	if (!reuse_cmdline)
+		free(reuse_cmdline);
+
 	if (cmdline) {
 		cmdline_len = strlen(cmdline) + 1;
 	} else {
@@ -175,6 +185,8 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
 {
 	struct mem_ehdr ehdr;
 	char *cmdline, *modified_cmdline = NULL;
+	char *reuse_cmdline = NULL;
+	char *append_cmdline = NULL;
 	const char *devicetreeblob;
 	uint64_t max_addr, hole_addr;
 	char *seg_buf = NULL;
@@ -204,6 +216,7 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
 		{ "devicetreeblob",     1, NULL, OPT_DEVICETREEBLOB },
 		{ "dtb",                1, NULL, OPT_DEVICETREEBLOB },
 		{ "args-linux",		0, NULL, OPT_ARGS_IGNORE },
+		{ "reuse-cmdline",	0, NULL, OPT_REUSE_CMDLINE},
 		{ 0,                    0, NULL, 0 },
 	};
 
@@ -229,7 +242,7 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
 			if (opt < OPT_ARCH_MAX)
 				break;
 		case OPT_APPEND:
-			cmdline = optarg;
+			append_cmdline = optarg;
 			break;
 		case OPT_RAMDISK:
 			ramdisk = optarg;
@@ -239,9 +252,16 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
 			break;
 		case OPT_ARGS_IGNORE:
 			break;
+		case OPT_REUSE_CMDLINE:
+			reuse_cmdline = get_command_line();
+			break;
 		}
 	}
 
+	cmdline = concat_cmdline(reuse_cmdline, append_cmdline);
+	if (!reuse_cmdline)
+		free(reuse_cmdline);
+
 	if (!cmdline)
 		fprintf(stdout, "Warning: append= option is not passed. Using the first kernel root partition\n");
 
@@ -469,6 +489,7 @@ void elf_ppc64_usage(void)
 	fprintf(stderr, "     --devicetreeblob=<filename> Specify device tree blob file.\n");
 	fprintf(stderr, "                                 ");
 	fprintf(stderr, "Not applicable while using --kexec-file-syscall.\n");
+	fprintf(stderr, "     --reuse-cmdline Use kernel command line from running system.\n");
 	fprintf(stderr, "     --dtb=<filename> same as --devicetreeblob.\n");
 
 	fprintf(stderr, "elf support is still broken\n");
-- 
2.33.1