All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vivek Goyal <vgoyal@redhat.com>
To: Greg KH <gregkh@linuxfoundation.org>
Cc: mjg59@srcf.ucam.org, hpa@zytor.com, kexec@lists.infradead.org,
	linux-kernel@vger.kernel.org, ebiederm@xmission.com
Subject: Re: [PATCH 0/6] kexec: A new system call to allow in kernel loading
Date: Thu, 21 Nov 2013 14:46:23 -0500	[thread overview]
Message-ID: <20131121194623.GP16208@redhat.com> (raw)
In-Reply-To: <20131121190729.GI16208@redhat.com>

On Thu, Nov 21, 2013 at 02:07:29PM -0500, Vivek Goyal wrote:

[..]
> > Very good stuff, thanks for working on this.  How have you been testing
> > this on the userspace side?  Are there patches to kexec, or are you just
> > using a small test program with the new syscall?
> 
> I wrote a patch for kexec-tools. One can choose to use new system call
> by passing command line option --use-kexec2-syscall. I will post
> that patch soon in this mail thread.

I have been using following kexec-tools patch to test this code.

Thanks
Vivek


kexec-tools: Provide an option to make use of new system call

This patch provides and option --use-kexec2-syscall, to force use of
new system call for kexec. Default is to continue to use old syscall.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 kexec/arch/x86_64/kexec-bzImage64.c |   86 ++++++++++++++++++++++++++
 kexec/kexec-syscall.h               |   24 +++++++
 kexec/kexec.c                       |  118 +++++++++++++++++++++++++++++++++++-
 kexec/kexec.h                       |    9 ++
 4 files changed, 234 insertions(+), 3 deletions(-)

Index: kexec-tools/kexec/kexec.c
===================================================================
--- kexec-tools.orig/kexec/kexec.c	2013-11-20 10:28:26.652380051 -0500
+++ kexec-tools/kexec/kexec.c	2013-11-20 11:31:44.906046486 -0500
@@ -51,6 +51,7 @@
 unsigned long long mem_min = 0;
 unsigned long long mem_max = ULONG_MAX;
 static unsigned long kexec_flags = 0;
+static unsigned long kexec2_flags = 0;
 int kexec_debug = 0;
 
 void die(const char *fmt, ...)
@@ -781,6 +782,19 @@ static int my_load(const char *type, int
 	return result;
 }
 
+static int kexec2_unload(unsigned long kexec2_flags)
+{
+	int ret = 0;
+
+	ret = kexec_file_load(-1, -1, NULL, 0, kexec2_flags);
+	if (ret != 0) {
+		/* The unload failed, print some debugging information */
+		fprintf(stderr, "kexec_file_load(unload) failed\n: %s\n",
+			strerror(errno));
+	}
+	return ret;
+}
+
 static int k_unload (unsigned long kexec_flags)
 {
 	int result;
@@ -919,6 +933,7 @@ void usage(void)
 	       "                      (0 means it's not jump back or\n"
 	       "                      preserve context)\n"
 	       "                      to original kernel.\n"
+	       " -s --use-kexec2-syscall Use new syscall for kexec operation\n"
 	       " -d, --debug           Enable debugging to help spot a failure.\n"
 	       "\n"
 	       "Supported kernel file types and options: \n");
@@ -1066,6 +1081,70 @@ char *concat_cmdline(const char *base, c
 	return cmdline;
 }
 
+/* New file based kexec system call related code */
+static int kexec2_load(int fileind, int argc, char **argv,
+			unsigned long flags) {
+
+	char *kernel;
+	int kernel_fd, i;
+	struct kexec_info info;
+	int ret = 0;
+	char *kernel_buf;
+	off_t kernel_size;
+
+	memset(&info, 0, sizeof(info));
+	info.segment = NULL;
+	info.nr_segments = 0;
+	info.entry = NULL;
+	info.backup_start = 0;
+	info.kexec_flags = flags;
+
+	info.file_mode = 1;
+	info.initrd_fd = -1;
+
+	if (argc - fileind <= 0) {
+		fprintf(stderr, "No kernel specified\n");
+		usage();
+		return -1;
+	}
+
+	kernel = argv[fileind];
+
+	kernel_fd = open(kernel, O_RDONLY);
+	if (kernel_fd == -1) {
+		fprintf(stderr, "Failed to open file %s:%s\n", kernel,
+				strerror(errno));
+		return -1;
+	}
+
+	/* slurp in the input kernel */
+	kernel_buf = slurp_decompress_file(kernel, &kernel_size);
+
+	for (i = 0; i < file_types; i++) {
+		if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
+			break;
+	}
+
+	if (i == file_types) {
+		fprintf(stderr, "Cannot determine the file type " "of %s\n",
+				kernel);
+		return -1;
+	}
+
+	ret = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info);
+	if (ret < 0) {
+		fprintf(stderr, "Cannot load %s\n", kernel);
+		return ret;
+	}
+
+	ret = kexec_file_load(kernel_fd, info.initrd_fd, info.command_line,
+			info.command_line_len, info.kexec_flags);
+	if (ret != 0)
+		fprintf(stderr, "kexec_file_load failed: %s\n",
+					strerror(errno));
+	return ret;
+}
+
 
 int main(int argc, char *argv[])
 {
@@ -1077,6 +1156,7 @@ int main(int argc, char *argv[])
 	int do_ifdown = 0;
 	int do_unload = 0;
 	int do_reuse_initrd = 0;
+	int do_use_kexec2_syscall = 0;
 	void *entry = 0;
 	char *type = 0;
 	char *endptr;
@@ -1089,6 +1169,23 @@ int main(int argc, char *argv[])
 	};
 	static const char short_options[] = KEXEC_ALL_OPT_STR;
 
+	/*
+	 * First check if --use-kexec2-syscall is set. That changes lot of
+	 * things
+	 */
+	while ((opt = getopt_long(argc, argv, short_options,
+				  options, 0)) != -1) {
+		switch(opt) {
+		case OPT_USE_KEXEC2_SYSCALL:
+			do_use_kexec2_syscall = 1;
+			break;
+		}
+	}
+
+	/* Reset getopt for the next pass. */
+	opterr = 1;
+	optind = 1;
+
 	while ((opt = getopt_long(argc, argv, short_options,
 				  options, 0)) != -1) {
 		switch(opt) {
@@ -1121,6 +1218,8 @@ int main(int argc, char *argv[])
 			do_shutdown = 0;
 			do_sync = 0;
 			do_unload = 1;
+			if (do_use_kexec2_syscall)
+				kexec2_flags |= KEXEC_FILE_UNLOAD;
 			break;
 		case OPT_EXEC:
 			do_load = 0;
@@ -1163,7 +1262,10 @@ int main(int argc, char *argv[])
 			do_exec = 0;
 			do_shutdown = 0;
 			do_sync = 0;
-			kexec_flags = KEXEC_ON_CRASH;
+			if (do_use_kexec2_syscall)
+				kexec2_flags |= KEXEC_FILE_ON_CRASH;
+			else
+				kexec_flags = KEXEC_ON_CRASH;
 			break;
 		case OPT_MEM_MIN:
 			mem_min = strtoul(optarg, &endptr, 0);
@@ -1188,6 +1290,9 @@ int main(int argc, char *argv[])
 		case OPT_REUSE_INITRD:
 			do_reuse_initrd = 1;
 			break;
+		case OPT_USE_KEXEC2_SYSCALL:
+			/* We already parsed it. Nothing to do. */
+			break;
 		default:
 			break;
 		}
@@ -1232,10 +1337,17 @@ int main(int argc, char *argv[])
 	}
 
 	if (do_unload) {
-		result = k_unload(kexec_flags);
+		if (do_use_kexec2_syscall)
+			result = kexec2_unload(kexec2_flags);
+		else
+			result = k_unload(kexec_flags);
 	}
 	if (do_load && (result == 0)) {
-		result = my_load(type, fileind, argc, argv, kexec_flags, entry);
+		if (do_use_kexec2_syscall)
+			result = kexec2_load(fileind, argc, argv, kexec2_flags);
+		else
+			result = my_load(type, fileind, argc, argv,
+						kexec_flags, entry);
 	}
 	/* Don't shutdown unless there is something to reboot to! */
 	if ((result == 0) && (do_shutdown || do_exec) && !kexec_loaded()) {
Index: kexec-tools/kexec/kexec.h
===================================================================
--- kexec-tools.orig/kexec/kexec.h	2013-11-20 10:28:26.652380051 -0500
+++ kexec-tools/kexec/kexec.h	2013-11-20 10:28:47.806336565 -0500
@@ -154,6 +154,13 @@ struct kexec_info {
 	unsigned long kexec_flags;
 	unsigned long backup_src_start;
 	unsigned long backup_src_size;
+	/* Set to 1 if we are using kexec2 syscall */
+	unsigned long file_mode :1;
+
+	/* Filled by kernel image processing code */
+	int initrd_fd;
+	char *command_line;
+	int command_line_len;
 };
 
 struct arch_map_entry {
@@ -205,6 +212,7 @@ extern int file_types;
 #define OPT_UNLOAD		'u'
 #define OPT_TYPE		't'
 #define OPT_PANIC		'p'
+#define OPT_USE_KEXEC2_SYSCALL	's'
 #define OPT_MEM_MIN             256
 #define OPT_MEM_MAX             257
 #define OPT_REUSE_INITRD	258
@@ -228,6 +236,7 @@ extern int file_types;
 	{ "mem-min",		1, 0, OPT_MEM_MIN }, \
 	{ "mem-max",		1, 0, OPT_MEM_MAX }, \
 	{ "reuseinitrd",	0, 0, OPT_REUSE_INITRD }, \
+	{ "use-kexec2-syscall",	0, 0, OPT_USE_KEXEC2_SYSCALL }, \
 	{ "debug",		0, 0, OPT_DEBUG }, \
 
 #define KEXEC_OPT_STR "h?vdfxluet:p"
Index: kexec-tools/kexec/arch/x86_64/kexec-bzImage64.c
===================================================================
--- kexec-tools.orig/kexec/arch/x86_64/kexec-bzImage64.c	2013-11-20 10:28:26.652380051 -0500
+++ kexec-tools/kexec/arch/x86_64/kexec-bzImage64.c	2013-11-20 10:28:47.807336610 -0500
@@ -229,6 +229,89 @@ static int do_bzImage64_load(struct kexe
 	return 0;
 }
 
+/* This assumes file is being loaded using file based kexec2 syscall */
+int bzImage64_load_file(int argc, char **argv, struct kexec_info *info)
+{
+	int ret = 0;
+	char *command_line = NULL, *tmp_cmdline = NULL;
+	const char *ramdisk = NULL, *append = NULL;
+	int entry_16bit = 0, entry_32bit = 0;
+	int opt;
+	int command_line_len;
+
+	/* See options.h -- add any more there, too. */
+	static const struct option options[] = {
+		KEXEC_ARCH_OPTIONS
+		{ "command-line",	1, 0, OPT_APPEND },
+		{ "append",		1, 0, OPT_APPEND },
+		{ "reuse-cmdline",	0, 0, OPT_REUSE_CMDLINE },
+		{ "initrd",		1, 0, OPT_RAMDISK },
+		{ "ramdisk",		1, 0, OPT_RAMDISK },
+		{ "real-mode",		0, 0, OPT_REAL_MODE },
+		{ "entry-32bit",	0, 0, OPT_ENTRY_32BIT },
+		{ 0,			0, 0, 0 },
+	};
+	static const char short_options[] = KEXEC_ARCH_OPT_STR "d";
+
+	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:
+			append = optarg;
+			break;
+		case OPT_REUSE_CMDLINE:
+			tmp_cmdline = get_command_line();
+			break;
+		case OPT_RAMDISK:
+			ramdisk = optarg;
+			break;
+		case OPT_REAL_MODE:
+			entry_16bit = 1;
+			break;
+		case OPT_ENTRY_32BIT:
+			entry_32bit = 1;
+			break;
+		}
+	}
+	command_line = concat_cmdline(tmp_cmdline, append);
+	if (tmp_cmdline)
+		free(tmp_cmdline);
+	command_line_len = 0;
+	if (command_line) {
+		command_line_len = strlen(command_line) + 1;
+	} else {
+		command_line = strdup("\0");
+		command_line_len = 1;
+	}
+
+	if (entry_16bit || entry_32bit) {
+		fprintf(stderr, "Kexec2 syscall does not support 16bit"
+			" or 32bit entry yet\n");
+		ret = -1;
+		goto out;
+	}
+
+	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 = command_line;
+	info->command_line_len = command_line_len;
+	return ret;
+out:
+	free(command_line);
+	return ret;
+}
+
 int bzImage64_load(int argc, char **argv, const char *buf, off_t len,
 	struct kexec_info *info)
 {
@@ -241,6 +324,9 @@ int bzImage64_load(int argc, char **argv
 	int opt;
 	int result;
 
+	if (info->file_mode)
+		return bzImage64_load_file(argc, argv, info);
+
 	/* See options.h -- add any more there, too. */
 	static const struct option options[] = {
 		KEXEC_ARCH_OPTIONS
Index: kexec-tools/kexec/kexec-syscall.h
===================================================================
--- kexec-tools.orig/kexec/kexec-syscall.h	2013-11-20 10:28:26.652380051 -0500
+++ kexec-tools/kexec/kexec-syscall.h	2013-11-20 10:28:47.808336655 -0500
@@ -50,6 +50,18 @@
 #endif
 #endif /*ifndef __NR_kexec_load*/
 
+#ifndef __NR_kexec_file_load
+
+#ifdef __x86_64__
+#define __NR_kexec_file_load	314
+#endif
+
+#ifndef __NR_kexec_file_load
+#error Unknown processor architecture.  Needs a kexec_load syscall number.
+#endif
+
+#endif /*ifndef __NR_kexec_file_load*/
+
 struct kexec_segment;
 
 static inline long kexec_load(void *entry, unsigned long nr_segments,
@@ -58,10 +70,22 @@ static inline long kexec_load(void *entr
 	return (long) syscall(__NR_kexec_load, entry, nr_segments, segments, flags);
 }
 
+static inline long kexec_file_load(int kernel_fd, int initrd_fd,
+			const char *cmdline_ptr, unsigned long cmdline_len,
+			unsigned long flags)
+{
+	return (long) syscall(__NR_kexec_file_load, kernel_fd, initrd_fd,
+				cmdline_ptr, cmdline_len, flags);
+}
+
 #define KEXEC_ON_CRASH		0x00000001
 #define KEXEC_PRESERVE_CONTEXT	0x00000002
 #define KEXEC_ARCH_MASK		0xffff0000
 
+/* Flags for kexec file based system call */
+#define KEXEC_FILE_UNLOAD	0x00000001
+#define KEXEC_FILE_ON_CRASH	0x00000002
+
 /* These values match the ELF architecture values. 
  * Unless there is a good reason that should continue to be the case.
  */

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

WARNING: multiple messages have this Message-ID (diff)
From: Vivek Goyal <vgoyal@redhat.com>
To: Greg KH <gregkh@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org, kexec@lists.infradead.org,
	ebiederm@xmission.com, hpa@zytor.com, mjg59@srcf.ucam.org
Subject: Re: [PATCH 0/6] kexec: A new system call to allow in kernel loading
Date: Thu, 21 Nov 2013 14:46:23 -0500	[thread overview]
Message-ID: <20131121194623.GP16208@redhat.com> (raw)
In-Reply-To: <20131121190729.GI16208@redhat.com>

On Thu, Nov 21, 2013 at 02:07:29PM -0500, Vivek Goyal wrote:

[..]
> > Very good stuff, thanks for working on this.  How have you been testing
> > this on the userspace side?  Are there patches to kexec, or are you just
> > using a small test program with the new syscall?
> 
> I wrote a patch for kexec-tools. One can choose to use new system call
> by passing command line option --use-kexec2-syscall. I will post
> that patch soon in this mail thread.

I have been using following kexec-tools patch to test this code.

Thanks
Vivek


kexec-tools: Provide an option to make use of new system call

This patch provides and option --use-kexec2-syscall, to force use of
new system call for kexec. Default is to continue to use old syscall.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 kexec/arch/x86_64/kexec-bzImage64.c |   86 ++++++++++++++++++++++++++
 kexec/kexec-syscall.h               |   24 +++++++
 kexec/kexec.c                       |  118 +++++++++++++++++++++++++++++++++++-
 kexec/kexec.h                       |    9 ++
 4 files changed, 234 insertions(+), 3 deletions(-)

Index: kexec-tools/kexec/kexec.c
===================================================================
--- kexec-tools.orig/kexec/kexec.c	2013-11-20 10:28:26.652380051 -0500
+++ kexec-tools/kexec/kexec.c	2013-11-20 11:31:44.906046486 -0500
@@ -51,6 +51,7 @@
 unsigned long long mem_min = 0;
 unsigned long long mem_max = ULONG_MAX;
 static unsigned long kexec_flags = 0;
+static unsigned long kexec2_flags = 0;
 int kexec_debug = 0;
 
 void die(const char *fmt, ...)
@@ -781,6 +782,19 @@ static int my_load(const char *type, int
 	return result;
 }
 
+static int kexec2_unload(unsigned long kexec2_flags)
+{
+	int ret = 0;
+
+	ret = kexec_file_load(-1, -1, NULL, 0, kexec2_flags);
+	if (ret != 0) {
+		/* The unload failed, print some debugging information */
+		fprintf(stderr, "kexec_file_load(unload) failed\n: %s\n",
+			strerror(errno));
+	}
+	return ret;
+}
+
 static int k_unload (unsigned long kexec_flags)
 {
 	int result;
@@ -919,6 +933,7 @@ void usage(void)
 	       "                      (0 means it's not jump back or\n"
 	       "                      preserve context)\n"
 	       "                      to original kernel.\n"
+	       " -s --use-kexec2-syscall Use new syscall for kexec operation\n"
 	       " -d, --debug           Enable debugging to help spot a failure.\n"
 	       "\n"
 	       "Supported kernel file types and options: \n");
@@ -1066,6 +1081,70 @@ char *concat_cmdline(const char *base, c
 	return cmdline;
 }
 
+/* New file based kexec system call related code */
+static int kexec2_load(int fileind, int argc, char **argv,
+			unsigned long flags) {
+
+	char *kernel;
+	int kernel_fd, i;
+	struct kexec_info info;
+	int ret = 0;
+	char *kernel_buf;
+	off_t kernel_size;
+
+	memset(&info, 0, sizeof(info));
+	info.segment = NULL;
+	info.nr_segments = 0;
+	info.entry = NULL;
+	info.backup_start = 0;
+	info.kexec_flags = flags;
+
+	info.file_mode = 1;
+	info.initrd_fd = -1;
+
+	if (argc - fileind <= 0) {
+		fprintf(stderr, "No kernel specified\n");
+		usage();
+		return -1;
+	}
+
+	kernel = argv[fileind];
+
+	kernel_fd = open(kernel, O_RDONLY);
+	if (kernel_fd == -1) {
+		fprintf(stderr, "Failed to open file %s:%s\n", kernel,
+				strerror(errno));
+		return -1;
+	}
+
+	/* slurp in the input kernel */
+	kernel_buf = slurp_decompress_file(kernel, &kernel_size);
+
+	for (i = 0; i < file_types; i++) {
+		if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
+			break;
+	}
+
+	if (i == file_types) {
+		fprintf(stderr, "Cannot determine the file type " "of %s\n",
+				kernel);
+		return -1;
+	}
+
+	ret = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info);
+	if (ret < 0) {
+		fprintf(stderr, "Cannot load %s\n", kernel);
+		return ret;
+	}
+
+	ret = kexec_file_load(kernel_fd, info.initrd_fd, info.command_line,
+			info.command_line_len, info.kexec_flags);
+	if (ret != 0)
+		fprintf(stderr, "kexec_file_load failed: %s\n",
+					strerror(errno));
+	return ret;
+}
+
 
 int main(int argc, char *argv[])
 {
@@ -1077,6 +1156,7 @@ int main(int argc, char *argv[])
 	int do_ifdown = 0;
 	int do_unload = 0;
 	int do_reuse_initrd = 0;
+	int do_use_kexec2_syscall = 0;
 	void *entry = 0;
 	char *type = 0;
 	char *endptr;
@@ -1089,6 +1169,23 @@ int main(int argc, char *argv[])
 	};
 	static const char short_options[] = KEXEC_ALL_OPT_STR;
 
+	/*
+	 * First check if --use-kexec2-syscall is set. That changes lot of
+	 * things
+	 */
+	while ((opt = getopt_long(argc, argv, short_options,
+				  options, 0)) != -1) {
+		switch(opt) {
+		case OPT_USE_KEXEC2_SYSCALL:
+			do_use_kexec2_syscall = 1;
+			break;
+		}
+	}
+
+	/* Reset getopt for the next pass. */
+	opterr = 1;
+	optind = 1;
+
 	while ((opt = getopt_long(argc, argv, short_options,
 				  options, 0)) != -1) {
 		switch(opt) {
@@ -1121,6 +1218,8 @@ int main(int argc, char *argv[])
 			do_shutdown = 0;
 			do_sync = 0;
 			do_unload = 1;
+			if (do_use_kexec2_syscall)
+				kexec2_flags |= KEXEC_FILE_UNLOAD;
 			break;
 		case OPT_EXEC:
 			do_load = 0;
@@ -1163,7 +1262,10 @@ int main(int argc, char *argv[])
 			do_exec = 0;
 			do_shutdown = 0;
 			do_sync = 0;
-			kexec_flags = KEXEC_ON_CRASH;
+			if (do_use_kexec2_syscall)
+				kexec2_flags |= KEXEC_FILE_ON_CRASH;
+			else
+				kexec_flags = KEXEC_ON_CRASH;
 			break;
 		case OPT_MEM_MIN:
 			mem_min = strtoul(optarg, &endptr, 0);
@@ -1188,6 +1290,9 @@ int main(int argc, char *argv[])
 		case OPT_REUSE_INITRD:
 			do_reuse_initrd = 1;
 			break;
+		case OPT_USE_KEXEC2_SYSCALL:
+			/* We already parsed it. Nothing to do. */
+			break;
 		default:
 			break;
 		}
@@ -1232,10 +1337,17 @@ int main(int argc, char *argv[])
 	}
 
 	if (do_unload) {
-		result = k_unload(kexec_flags);
+		if (do_use_kexec2_syscall)
+			result = kexec2_unload(kexec2_flags);
+		else
+			result = k_unload(kexec_flags);
 	}
 	if (do_load && (result == 0)) {
-		result = my_load(type, fileind, argc, argv, kexec_flags, entry);
+		if (do_use_kexec2_syscall)
+			result = kexec2_load(fileind, argc, argv, kexec2_flags);
+		else
+			result = my_load(type, fileind, argc, argv,
+						kexec_flags, entry);
 	}
 	/* Don't shutdown unless there is something to reboot to! */
 	if ((result == 0) && (do_shutdown || do_exec) && !kexec_loaded()) {
Index: kexec-tools/kexec/kexec.h
===================================================================
--- kexec-tools.orig/kexec/kexec.h	2013-11-20 10:28:26.652380051 -0500
+++ kexec-tools/kexec/kexec.h	2013-11-20 10:28:47.806336565 -0500
@@ -154,6 +154,13 @@ struct kexec_info {
 	unsigned long kexec_flags;
 	unsigned long backup_src_start;
 	unsigned long backup_src_size;
+	/* Set to 1 if we are using kexec2 syscall */
+	unsigned long file_mode :1;
+
+	/* Filled by kernel image processing code */
+	int initrd_fd;
+	char *command_line;
+	int command_line_len;
 };
 
 struct arch_map_entry {
@@ -205,6 +212,7 @@ extern int file_types;
 #define OPT_UNLOAD		'u'
 #define OPT_TYPE		't'
 #define OPT_PANIC		'p'
+#define OPT_USE_KEXEC2_SYSCALL	's'
 #define OPT_MEM_MIN             256
 #define OPT_MEM_MAX             257
 #define OPT_REUSE_INITRD	258
@@ -228,6 +236,7 @@ extern int file_types;
 	{ "mem-min",		1, 0, OPT_MEM_MIN }, \
 	{ "mem-max",		1, 0, OPT_MEM_MAX }, \
 	{ "reuseinitrd",	0, 0, OPT_REUSE_INITRD }, \
+	{ "use-kexec2-syscall",	0, 0, OPT_USE_KEXEC2_SYSCALL }, \
 	{ "debug",		0, 0, OPT_DEBUG }, \
 
 #define KEXEC_OPT_STR "h?vdfxluet:p"
Index: kexec-tools/kexec/arch/x86_64/kexec-bzImage64.c
===================================================================
--- kexec-tools.orig/kexec/arch/x86_64/kexec-bzImage64.c	2013-11-20 10:28:26.652380051 -0500
+++ kexec-tools/kexec/arch/x86_64/kexec-bzImage64.c	2013-11-20 10:28:47.807336610 -0500
@@ -229,6 +229,89 @@ static int do_bzImage64_load(struct kexe
 	return 0;
 }
 
+/* This assumes file is being loaded using file based kexec2 syscall */
+int bzImage64_load_file(int argc, char **argv, struct kexec_info *info)
+{
+	int ret = 0;
+	char *command_line = NULL, *tmp_cmdline = NULL;
+	const char *ramdisk = NULL, *append = NULL;
+	int entry_16bit = 0, entry_32bit = 0;
+	int opt;
+	int command_line_len;
+
+	/* See options.h -- add any more there, too. */
+	static const struct option options[] = {
+		KEXEC_ARCH_OPTIONS
+		{ "command-line",	1, 0, OPT_APPEND },
+		{ "append",		1, 0, OPT_APPEND },
+		{ "reuse-cmdline",	0, 0, OPT_REUSE_CMDLINE },
+		{ "initrd",		1, 0, OPT_RAMDISK },
+		{ "ramdisk",		1, 0, OPT_RAMDISK },
+		{ "real-mode",		0, 0, OPT_REAL_MODE },
+		{ "entry-32bit",	0, 0, OPT_ENTRY_32BIT },
+		{ 0,			0, 0, 0 },
+	};
+	static const char short_options[] = KEXEC_ARCH_OPT_STR "d";
+
+	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:
+			append = optarg;
+			break;
+		case OPT_REUSE_CMDLINE:
+			tmp_cmdline = get_command_line();
+			break;
+		case OPT_RAMDISK:
+			ramdisk = optarg;
+			break;
+		case OPT_REAL_MODE:
+			entry_16bit = 1;
+			break;
+		case OPT_ENTRY_32BIT:
+			entry_32bit = 1;
+			break;
+		}
+	}
+	command_line = concat_cmdline(tmp_cmdline, append);
+	if (tmp_cmdline)
+		free(tmp_cmdline);
+	command_line_len = 0;
+	if (command_line) {
+		command_line_len = strlen(command_line) + 1;
+	} else {
+		command_line = strdup("\0");
+		command_line_len = 1;
+	}
+
+	if (entry_16bit || entry_32bit) {
+		fprintf(stderr, "Kexec2 syscall does not support 16bit"
+			" or 32bit entry yet\n");
+		ret = -1;
+		goto out;
+	}
+
+	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 = command_line;
+	info->command_line_len = command_line_len;
+	return ret;
+out:
+	free(command_line);
+	return ret;
+}
+
 int bzImage64_load(int argc, char **argv, const char *buf, off_t len,
 	struct kexec_info *info)
 {
@@ -241,6 +324,9 @@ int bzImage64_load(int argc, char **argv
 	int opt;
 	int result;
 
+	if (info->file_mode)
+		return bzImage64_load_file(argc, argv, info);
+
 	/* See options.h -- add any more there, too. */
 	static const struct option options[] = {
 		KEXEC_ARCH_OPTIONS
Index: kexec-tools/kexec/kexec-syscall.h
===================================================================
--- kexec-tools.orig/kexec/kexec-syscall.h	2013-11-20 10:28:26.652380051 -0500
+++ kexec-tools/kexec/kexec-syscall.h	2013-11-20 10:28:47.808336655 -0500
@@ -50,6 +50,18 @@
 #endif
 #endif /*ifndef __NR_kexec_load*/
 
+#ifndef __NR_kexec_file_load
+
+#ifdef __x86_64__
+#define __NR_kexec_file_load	314
+#endif
+
+#ifndef __NR_kexec_file_load
+#error Unknown processor architecture.  Needs a kexec_load syscall number.
+#endif
+
+#endif /*ifndef __NR_kexec_file_load*/
+
 struct kexec_segment;
 
 static inline long kexec_load(void *entry, unsigned long nr_segments,
@@ -58,10 +70,22 @@ static inline long kexec_load(void *entr
 	return (long) syscall(__NR_kexec_load, entry, nr_segments, segments, flags);
 }
 
+static inline long kexec_file_load(int kernel_fd, int initrd_fd,
+			const char *cmdline_ptr, unsigned long cmdline_len,
+			unsigned long flags)
+{
+	return (long) syscall(__NR_kexec_file_load, kernel_fd, initrd_fd,
+				cmdline_ptr, cmdline_len, flags);
+}
+
 #define KEXEC_ON_CRASH		0x00000001
 #define KEXEC_PRESERVE_CONTEXT	0x00000002
 #define KEXEC_ARCH_MASK		0xffff0000
 
+/* Flags for kexec file based system call */
+#define KEXEC_FILE_UNLOAD	0x00000001
+#define KEXEC_FILE_ON_CRASH	0x00000002
+
 /* These values match the ELF architecture values. 
  * Unless there is a good reason that should continue to be the case.
  */

  reply	other threads:[~2013-11-21 19:46 UTC|newest]

Thread overview: 180+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-20 17:50 [PATCH 0/6] kexec: A new system call to allow in kernel loading Vivek Goyal
2013-11-20 17:50 ` Vivek Goyal
2013-11-20 17:50 ` [PATCH 1/6] kexec: Export vmcoreinfo note size properly Vivek Goyal
2013-11-20 17:50   ` Vivek Goyal
2013-11-21 18:59   ` Greg KH
2013-11-21 18:59     ` Greg KH
2013-11-21 19:08     ` Vivek Goyal
2013-11-21 19:08       ` Vivek Goyal
2013-11-20 17:50 ` [PATCH 2/6] kexec: Move segment verification code in a separate function Vivek Goyal
2013-11-20 17:50   ` Vivek Goyal
2013-11-20 17:50 ` [PATCH 3/6] resource: Provide new functions to walk through resources Vivek Goyal
2013-11-20 17:50   ` Vivek Goyal
2013-11-20 17:50 ` [PATCH 4/6] kexec: A new system call, kexec_file_load, for in kernel kexec Vivek Goyal
2013-11-20 17:50   ` Vivek Goyal
2013-11-21 19:03   ` Greg KH
2013-11-21 19:03     ` Greg KH
2013-11-21 19:06     ` Matthew Garrett
2013-11-21 19:06       ` Matthew Garrett
2013-11-21 19:13       ` Vivek Goyal
2013-11-21 19:13         ` Vivek Goyal
2013-11-21 19:19         ` Matthew Garrett
2013-11-21 19:19           ` Matthew Garrett
2013-11-21 19:24           ` Vivek Goyal
2013-11-21 19:24             ` Vivek Goyal
2013-11-22 18:57           ` Vivek Goyal
2013-11-22 18:57             ` Vivek Goyal
2013-11-23  3:39             ` Eric W. Biederman
2013-11-23  3:39               ` Eric W. Biederman
2013-11-25 16:39               ` Vivek Goyal
2013-11-25 16:39                 ` Vivek Goyal
2013-11-26 12:23                 ` Eric W. Biederman
2013-11-26 12:23                   ` Eric W. Biederman
2013-11-26 14:27                   ` Vivek Goyal
2013-11-26 14:27                     ` Vivek Goyal
2013-12-19 12:54                     ` Torsten Duwe
2013-12-19 12:54                       ` Torsten Duwe
2013-12-20 14:19                       ` Vivek Goyal
2013-12-20 14:19                         ` Vivek Goyal
2013-12-20 23:11                         ` Eric W. Biederman
2013-12-20 23:11                           ` Eric W. Biederman
2013-12-20 23:20                           ` Kees Cook
2013-12-20 23:20                             ` Kees Cook
2013-12-21 11:38                             ` Torsten Duwe
2013-12-21 11:38                               ` Torsten Duwe
2014-01-02 20:39                             ` Vivek Goyal
2014-01-02 20:39                               ` Vivek Goyal
2014-01-02 20:56                               ` H. Peter Anvin
2014-01-02 20:56                                 ` H. Peter Anvin
2014-01-06 21:33                                 ` Josh Boyer
2014-01-06 21:33                                   ` Josh Boyer
2014-01-07  4:22                                   ` H. Peter Anvin
2014-01-07  4:22                                     ` H. Peter Anvin
2013-12-20 23:20                           ` H. Peter Anvin
2013-12-20 23:20                             ` H. Peter Anvin
2013-12-21  1:32                             ` Eric W. Biederman
2013-12-21  1:32                               ` Eric W. Biederman
2013-12-21  3:32                               ` H. Peter Anvin
2013-12-21  3:32                                 ` H. Peter Anvin
2013-12-21 12:15                                 ` Torsten Duwe
2013-12-21 12:15                                   ` Torsten Duwe
2013-11-21 19:16     ` Vivek Goyal
2013-11-21 19:16       ` Vivek Goyal
2013-11-22  1:03     ` Kees Cook
2013-11-22  1:03       ` Kees Cook
2013-11-22  2:13       ` Vivek Goyal
2013-11-22  2:13         ` Vivek Goyal
2013-11-22 20:42   ` Jiri Kosina
2013-11-22 20:42     ` Jiri Kosina
2014-01-17 19:17     ` Vivek Goyal
2014-01-17 19:17       ` Vivek Goyal
2013-11-29  3:10   ` Baoquan He
2013-11-29  3:10     ` Baoquan He
2013-12-02 15:27     ` WANG Chao
2013-12-02 15:27       ` WANG Chao
2013-12-02 15:44     ` Vivek Goyal
2013-12-02 15:44       ` Vivek Goyal
2013-12-04  1:35       ` Baoquan He
2013-12-04  1:35         ` Baoquan He
2013-12-04 17:19         ` Vivek Goyal
2013-12-04 17:19           ` Vivek Goyal
2013-12-04  1:56   ` Baoquan He
2013-12-04  1:56     ` Baoquan He
2013-12-04  8:19     ` Baoquan He
2013-12-04  8:19       ` Baoquan He
2013-12-04 17:32     ` Vivek Goyal
2013-12-04 17:32       ` Vivek Goyal
2013-11-20 17:50 ` [PATCH 5/6] kexec-bzImage: Support for loading bzImage using 64bit entry Vivek Goyal
2013-11-20 17:50   ` Vivek Goyal
2013-11-21 19:07   ` Greg KH
2013-11-21 19:07     ` Greg KH
2013-11-21 19:21     ` Vivek Goyal
2013-11-21 19:21       ` Vivek Goyal
2013-11-22 15:24       ` H. Peter Anvin
2013-11-22 15:24         ` H. Peter Anvin
2013-11-28 11:35   ` Baoquan He
2013-11-28 11:35     ` Baoquan He
2013-12-02 15:36     ` Vivek Goyal
2013-12-02 15:36       ` Vivek Goyal
2013-11-20 17:50 ` [PATCH 6/6] kexec: Support for Kexec on panic using new system call Vivek Goyal
2013-11-20 17:50   ` Vivek Goyal
2013-11-28 11:28   ` Baoquan He
2013-11-28 11:28     ` Baoquan He
2013-12-02 15:30     ` Vivek Goyal
2013-12-02 15:30       ` Vivek Goyal
2013-12-04  1:51       ` Baoquan He
2013-12-04  1:51         ` Baoquan He
2013-12-04 17:20         ` Vivek Goyal
2013-12-04 17:20           ` Vivek Goyal
2013-12-04  1:41   ` Baoquan He
2013-12-04  1:41     ` Baoquan He
2013-12-04 17:19     ` Vivek Goyal
2013-12-04 17:19       ` Vivek Goyal
2013-11-21 18:58 ` [PATCH 0/6] kexec: A new system call to allow in kernel loading Greg KH
2013-11-21 18:58   ` Greg KH
2013-11-21 19:07   ` Vivek Goyal
2013-11-21 19:07     ` Vivek Goyal
2013-11-21 19:46     ` Vivek Goyal [this message]
2013-11-21 19:46       ` Vivek Goyal
2013-11-21 19:06 ` Geert Uytterhoeven
2013-11-21 19:06   ` Geert Uytterhoeven
2013-11-21 19:14   ` Vivek Goyal
2013-11-21 19:14     ` Vivek Goyal
2013-11-21 23:07 ` Eric W. Biederman
2013-11-21 23:07   ` Eric W. Biederman
2013-11-22  1:28   ` H. Peter Anvin
2013-11-22  1:28     ` H. Peter Anvin
2013-11-22  2:35     ` Vivek Goyal
2013-11-22  2:35       ` Vivek Goyal
2013-11-22  2:40       ` H. Peter Anvin
2013-11-22  2:40         ` H. Peter Anvin
2013-11-22  1:55   ` Vivek Goyal
2013-11-22  1:55     ` Vivek Goyal
2013-11-22  9:09     ` Geert Uytterhoeven
2013-11-22  9:09       ` Geert Uytterhoeven
2013-11-22 13:30       ` Jiri Kosina
2013-11-22 13:30         ` Jiri Kosina
2013-11-22 13:46         ` Vivek Goyal
2013-11-22 13:46           ` Vivek Goyal
2013-11-22 13:50           ` Jiri Kosina
2013-11-22 13:50             ` Jiri Kosina
2013-11-22 15:33             ` Vivek Goyal
2013-11-22 15:33               ` Vivek Goyal
2013-11-22 17:45               ` Kees Cook
2013-11-22 17:45                 ` Kees Cook
2013-11-22 13:43       ` Vivek Goyal
2013-11-22 13:43         ` Vivek Goyal
2013-11-22 15:25         ` Geert Uytterhoeven
2013-11-22 15:25           ` Geert Uytterhoeven
2013-11-22 15:33           ` Jiri Kosina
2013-11-22 15:33             ` Jiri Kosina
2013-11-22 15:57             ` Eric Paris
2013-11-22 15:57               ` Eric Paris
2013-11-22 16:04               ` Jiri Kosina
2013-11-22 16:04                 ` Jiri Kosina
2013-11-22 16:08                 ` Vivek Goyal
2013-11-22 16:08                   ` Vivek Goyal
2013-11-22 13:34     ` Eric W. Biederman
2013-11-22 13:34       ` Eric W. Biederman
2013-11-22 14:19       ` Vivek Goyal
2013-11-22 14:19         ` Vivek Goyal
2013-11-22 19:48         ` Greg KH
2013-11-22 19:48           ` Greg KH
2013-11-23  3:23         ` Eric W. Biederman
2013-11-23  3:23           ` Eric W. Biederman
2013-12-04 19:34           ` Vivek Goyal
2013-12-04 19:34             ` Vivek Goyal
2013-12-05  4:10             ` Eric W. Biederman
2013-12-05  4:10               ` Eric W. Biederman
2013-11-25 10:04       ` Michael Holzheu
2013-11-25 10:04         ` Michael Holzheu
2013-11-25 15:36         ` Vivek Goyal
2013-11-25 15:36           ` Vivek Goyal
2013-11-25 16:15           ` Michael Holzheu
2013-11-25 16:15             ` Michael Holzheu
2013-11-22  0:55 ` HATAYAMA Daisuke
2013-11-22  0:55   ` HATAYAMA Daisuke
2013-11-22  2:03   ` Vivek Goyal
2013-11-22  2:03     ` Vivek Goyal
2013-12-03 13:23 ` Baoquan He
2013-12-03 13:23   ` Baoquan He

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20131121194623.GP16208@redhat.com \
    --to=vgoyal@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.