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
next prev parent reply other threads:[~2013-11-21 19:46 UTC|newest]
Thread overview: 90+ 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 ` [PATCH 1/6] kexec: Export vmcoreinfo note size properly Vivek Goyal
2013-11-21 18:59 ` Greg KH
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 ` [PATCH 3/6] resource: Provide new functions to walk through resources 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-21 19:03 ` Greg KH
2013-11-21 19:06 ` Matthew Garrett
2013-11-21 19:13 ` Vivek Goyal
2013-11-21 19:19 ` Matthew Garrett
2013-11-21 19:24 ` Vivek Goyal
2013-11-22 18:57 ` Vivek Goyal
2013-11-23 3:39 ` Eric W. Biederman
2013-11-25 16:39 ` Vivek Goyal
2013-11-26 12:23 ` Eric W. Biederman
2013-11-26 14:27 ` Vivek Goyal
2013-12-19 12:54 ` Torsten Duwe
2013-12-20 14:19 ` Vivek Goyal
2013-12-20 23:11 ` Eric W. Biederman
2013-12-20 23:20 ` Kees Cook
2013-12-21 11:38 ` Torsten Duwe
2014-01-02 20:39 ` Vivek Goyal
2014-01-02 20:56 ` H. Peter Anvin
2014-01-06 21:33 ` Josh Boyer
2014-01-07 4:22 ` H. Peter Anvin
2013-12-20 23:20 ` H. Peter Anvin
2013-12-21 1:32 ` Eric W. Biederman
2013-12-21 3:32 ` H. Peter Anvin
2013-12-21 12:15 ` Torsten Duwe
2013-11-21 19:16 ` Vivek Goyal
2013-11-22 1:03 ` Kees Cook
2013-11-22 2:13 ` Vivek Goyal
2013-11-22 20:42 ` Jiri Kosina
2014-01-17 19:17 ` Vivek Goyal
2013-11-29 3:10 ` Baoquan He
2013-12-02 15:27 ` WANG Chao
2013-12-02 15:44 ` Vivek Goyal
2013-12-04 1:35 ` Baoquan He
2013-12-04 17:19 ` Vivek Goyal
2013-12-04 1:56 ` Baoquan He
2013-12-04 8:19 ` Baoquan He
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-21 19:07 ` Greg KH
2013-11-21 19:21 ` Vivek Goyal
2013-11-22 15:24 ` H. Peter Anvin
2013-11-28 11:35 ` Baoquan He
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-28 11:28 ` Baoquan He
2013-12-02 15:30 ` Vivek Goyal
2013-12-04 1:51 ` Baoquan He
2013-12-04 17:20 ` Vivek Goyal
2013-12-04 1:41 ` Baoquan He
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 19:07 ` Vivek Goyal
2013-11-21 19:46 ` Vivek Goyal [this message]
2013-11-21 19:06 ` Geert Uytterhoeven
2013-11-21 19:14 ` Vivek Goyal
2013-11-21 23:07 ` Eric W. Biederman
2013-11-22 1:28 ` H. Peter Anvin
2013-11-22 2:35 ` Vivek Goyal
2013-11-22 2:40 ` H. Peter Anvin
2013-11-22 1:55 ` Vivek Goyal
2013-11-22 9:09 ` Geert Uytterhoeven
2013-11-22 13:30 ` Jiri Kosina
2013-11-22 13:46 ` Vivek Goyal
2013-11-22 13:50 ` Jiri Kosina
2013-11-22 15:33 ` Vivek Goyal
2013-11-22 17:45 ` Kees Cook
2013-11-22 13:43 ` Vivek Goyal
2013-11-22 15:25 ` Geert Uytterhoeven
2013-11-22 15:33 ` Jiri Kosina
2013-11-22 15:57 ` Eric Paris
2013-11-22 16:04 ` Jiri Kosina
2013-11-22 16:08 ` Vivek Goyal
2013-11-22 13:34 ` Eric W. Biederman
2013-11-22 14:19 ` Vivek Goyal
2013-11-22 19:48 ` Greg KH
2013-11-23 3:23 ` Eric W. Biederman
2013-12-04 19:34 ` Vivek Goyal
2013-12-05 4:10 ` Eric W. Biederman
2013-11-25 10:04 ` Michael Holzheu
2013-11-25 15:36 ` Vivek Goyal
2013-11-25 16:15 ` Michael Holzheu
2013-11-22 0:55 ` HATAYAMA Daisuke
2013-11-22 2:03 ` Vivek Goyal
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).