linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: takahiro.akashi@linaro.org (AKASHI Takahiro)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC 3/3] kexec: extend kexec_file_load system call
Date: Tue, 12 Jul 2016 10:42:01 +0900	[thread overview]
Message-ID: <20160712014201.11456-4-takahiro.akashi@linaro.org> (raw)
In-Reply-To: <20160712014201.11456-1-takahiro.akashi@linaro.org>

Device tree blob must be passed to a second kernel on DTB-capable
archs, like powerpc and arm64, but the current kernel interface
lacks this support.

This patch extends kexec_file_load system call by adding an extra
argument to this syscall so that an arbitrary number of file descriptors
can be handed out from user space to the kernel.

	long sys_kexec_file_load(int kernel_fd, int initrd_fd,
				 unsigned long cmdline_len,
				 const char __user *cmdline_ptr,
				 unsigned long flags,
				 const struct kexec_fdset __user *ufdset);

If KEXEC_FILE_EXTRA_FDS is set to the "flags" argument, the "ufdset"
argument points to the following struct buffer:

	struct kexec_fdset {
		int nr_fds;
		struct kexec_file_fd fds[0];
	}

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 include/linux/fs.h         |  1 +
 include/linux/kexec.h      |  2 +-
 include/linux/syscalls.h   |  4 +++-
 include/uapi/linux/kexec.h | 17 ++++++++++++++
 kernel/kexec_file.c        | 57 ++++++++++++++++++++++++++++++++++++++++------
 5 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index dd28814..6dd6fdf 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2634,6 +2634,7 @@ extern int do_pipe_flags(int *, int);
 	id(MODULE, kernel-module)		\
 	id(KEXEC_IMAGE, kexec-image)		\
 	id(KEXEC_INITRAMFS, kexec-initramfs)	\
+	id(KEXEC_DTB, kexec-dtb)		\
 	id(POLICY, security-policy)		\
 	id(MAX_ID, )
 
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 554c848..5f11bd5 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -277,7 +277,7 @@ extern int kexec_load_disabled;
 
 /* List of defined/legal kexec file flags */
 #define KEXEC_FILE_FLAGS	(KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
-				 KEXEC_FILE_NO_INITRAMFS)
+				 KEXEC_FILE_NO_INITRAMFS | KEXEC_FILE_EXTRA_FDS)
 
 #define VMCOREINFO_BYTES           (4096)
 #define VMCOREINFO_NOTE_NAME       "VMCOREINFO"
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index d022390..fc072bd 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -66,6 +66,7 @@ struct perf_event_attr;
 struct file_handle;
 struct sigaltstack;
 union bpf_attr;
+struct kexec_fdset;
 
 #include <linux/types.h>
 #include <linux/aio_abi.h>
@@ -321,7 +322,8 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
 asmlinkage long sys_kexec_file_load(int kernel_fd, int initrd_fd,
 				    unsigned long cmdline_len,
 				    const char __user *cmdline_ptr,
-				    unsigned long flags);
+				    unsigned long flags,
+				    const struct kexec_fdset __user *ufdset);
 
 asmlinkage long sys_exit(int error_code);
 asmlinkage long sys_exit_group(int error_code);
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index aae5ebf..adf53b6 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -23,6 +23,23 @@
 #define KEXEC_FILE_UNLOAD	0x00000001
 #define KEXEC_FILE_ON_CRASH	0x00000002
 #define KEXEC_FILE_NO_INITRAMFS	0x00000004
+#define KEXEC_FILE_EXTRA_FDS	0x00000008
+
+enum kexec_file_type {
+	KEXEC_FILE_TYPE_KERNEL,
+	KEXEC_FILE_TYPE_INITRAMFS,
+	KEXEC_FILE_TYPE_DTB,
+};
+
+struct kexec_file_fd {
+	enum kexec_file_type type;
+	int fd;
+};
+
+struct kexec_fdset {
+	int nr_fds;
+	struct kexec_file_fd fds[0];
+};
 
 /* These values match the ELF architecture values.
  * Unless there is a good reason that should continue to be the case.
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 7278329..451b4b0 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -137,11 +137,14 @@ void kimage_file_post_load_cleanup(struct kimage *image)
 static int
 kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 			     const char __user *cmdline_ptr,
-			     unsigned long cmdline_len, unsigned flags)
+			     unsigned long cmdline_len, unsigned long flags,
+			     const struct kexec_fdset __user *ufdset)
 {
-	int ret = 0;
+	int ret = 0, nr_fds, i;
 	void *ldata;
 	loff_t size;
+	struct kexec_fdset *fdset = NULL;
+	size_t fdset_size;
 
 	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
 				       &size, INT_MAX, READING_KEXEC_IMAGE);
@@ -174,6 +177,42 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 		image->initrd_buf_len = size;
 	}
 
+	if (flags & KEXEC_FILE_EXTRA_FDS) {
+		ret = copy_from_user(&nr_fds, ufdset, sizeof(int));
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		fdset_size = sizeof(struct kexec_fdset)
+				+ nr_fds * sizeof(struct kexec_file_fd);
+		fdset = kmalloc(fdset_size, GFP_KERNEL);
+		if (!fdset) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		ret = copy_from_user(fdset, ufdset, fdset_size);
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		for (i = 0; i < fdset->nr_fds; i++) {
+			if (fdset->fds[i].type == KEXEC_FILE_TYPE_DTB) {
+				ret = kernel_read_file_from_fd(fdset->fds[i].fd,
+						&image->dtb_buf, &size, INT_MAX,
+						READING_KEXEC_DTB);
+				if (ret)
+					goto out;
+				image->dtb_buf_len = size;
+			} else {
+				pr_debug("unknown file type %d failed.\n",
+						fdset->fds[i].type);
+			}
+		}
+	}
+
 	if (cmdline_len) {
 		image->cmdline_buf = kzalloc(cmdline_len, GFP_KERNEL);
 		if (!image->cmdline_buf) {
@@ -208,6 +247,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 	image->image_loader_data = ldata;
 out:
 	/* In case of error, free up all allocated memory in this function */
+	kfree(fdset);
+
 	if (ret)
 		kimage_file_post_load_cleanup(image);
 	return ret;
@@ -216,7 +257,8 @@ out:
 static int
 kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
 		       int initrd_fd, const char __user *cmdline_ptr,
-		       unsigned long cmdline_len, unsigned long flags)
+		       unsigned long cmdline_len, unsigned long flags,
+		       const struct kexec_fdset __user *ufdset)
 {
 	int ret;
 	struct kimage *image;
@@ -235,7 +277,8 @@ kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
 	}
 
 	ret = kimage_file_prepare_segments(image, kernel_fd, initrd_fd,
-					   cmdline_ptr, cmdline_len, flags);
+					   cmdline_ptr, cmdline_len, flags,
+					   ufdset);
 	if (ret)
 		goto out_free_image;
 
@@ -270,9 +313,9 @@ out_free_image:
 	return ret;
 }
 
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
 {
 	int ret = 0, i;
 	struct kimage **dest_image, *image;
@@ -309,7 +352,7 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		kimage_free(xchg(&kexec_crash_image, NULL));
 
 	ret = kimage_file_alloc_init(&image, kernel_fd, initrd_fd, cmdline_ptr,
-				     cmdline_len, flags);
+				     cmdline_len, flags, ufdset);
 	if (ret)
 		goto out;
 
-- 
2.9.0

  parent reply	other threads:[~2016-07-12  1:42 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-12  1:41 [RFC 0/3] extend kexec_file_load system call AKASHI Takahiro
2016-07-12  1:41 ` [RFC 1/3] syscall: add kexec_file_load to generic unistd.h AKASHI Takahiro
2016-07-12  1:42 ` [RFC 2/3] kexec: add dtb info to struct kimage AKASHI Takahiro
2016-07-12  1:42 ` AKASHI Takahiro [this message]
2016-07-15 13:09   ` [RFC 3/3] kexec: extend kexec_file_load system call Vivek Goyal
2016-07-15 13:19     ` Mark Rutland
2016-07-18  2:30       ` Dave Young
2016-07-18 10:07         ` Mark Rutland
2016-07-19  0:55           ` Dave Young
2016-07-19 10:52             ` Mark Rutland
2016-07-19 12:24               ` Vivek Goyal
2016-07-19 12:47                 ` Mark Rutland
2016-07-19 13:26                   ` Vivek Goyal
2016-07-20 11:41         ` David Laight
2016-07-21  9:21           ` Russell King - ARM Linux
2016-07-18  2:33     ` Dave Young
2016-07-27  0:24   ` [PATCH v2 " Thiago Jung Bauermann
2016-08-05 20:46     ` Thiago Jung Bauermann
2016-07-12 13:25 ` [RFC 0/3] " Eric W. Biederman
2016-07-12 13:58   ` Thiago Jung Bauermann
2016-07-12 14:02     ` Vivek Goyal
2016-07-12 23:45       ` Stewart Smith
2016-07-13 13:27         ` Vivek Goyal
2016-07-12 14:02   ` Arnd Bergmann
2016-07-12 14:18     ` Vivek Goyal
2016-07-12 14:24       ` Arnd Bergmann
2016-07-12 14:50         ` Mark Rutland
2016-07-13  2:36           ` Dave Young
2016-07-13  8:01             ` Arnd Bergmann
2016-07-13  8:23               ` Stewart Smith
2016-07-13  9:41               ` Mark Rutland
2016-07-13 13:13                 ` Arnd Bergmann
2016-07-13 18:45                   ` Thiago Jung Bauermann
2016-07-13 19:59                     ` Arnd Bergmann
2016-07-14  2:18                       ` Thiago Jung Bauermann
2016-07-14  8:29                         ` Arnd Bergmann
2016-07-15  1:44                           ` Thiago Jung Bauermann
2016-07-15  7:31                             ` Arnd Bergmann
2016-07-15 13:26                               ` Vivek Goyal
2016-07-15 13:33                                 ` Mark Rutland
2016-07-15 15:29                                   ` Thiago Jung Bauermann
2016-07-15 15:47                                     ` Mark Rutland
2016-07-15 13:42                                 ` Russell King - ARM Linux
2016-07-15 20:26                                   ` Arnd Bergmann
2016-07-15 21:03                                     ` Thiago Jung Bauermann
2016-07-22  0:09                                       ` Thiago Jung Bauermann
2016-07-22  0:53                                         ` Jeremy Kerr
2016-07-22  2:54                                         ` Michael Ellerman
2016-07-22 20:41                                           ` Thiago Jung Bauermann
2016-07-15  8:49                   ` Russell King - ARM Linux
2016-07-15 13:03                     ` Vivek Goyal
2016-07-13  9:34             ` Mark Rutland
2016-07-13 17:38               ` AKASHI Takahiro
2016-07-13 17:58                 ` Mark Rutland
2016-07-13 19:57                   ` Arnd Bergmann
2016-07-14 12:42                     ` Mark Rutland
2016-07-14  1:54                 ` Dave Young
2016-07-14  1:50               ` Dave Young
2016-07-12 16:25   ` Thiago Jung Bauermann
2016-07-12 20:58     ` Petr Tesarik
2016-07-12 21:22       ` Eric W. Biederman
2016-07-12 21:36         ` Eric W. Biederman
2016-07-12 21:53         ` Petr Tesarik
2016-07-12 22:18       ` Russell King - ARM Linux
2016-07-13  4:59         ` Stewart Smith
2016-07-13  7:36           ` Russell King - ARM Linux
2016-07-13  7:47             ` Ard Biesheuvel
2016-07-13  8:09               ` Russell King - ARM Linux
2016-07-13  8:20               ` Stewart Smith
2016-07-13  7:55             ` Stewart Smith
2016-07-13  8:26               ` Russell King - ARM Linux
2016-07-13  8:36                 ` Dave Young
2016-07-13  8:57                 ` Petr Tesarik
2016-07-13 13:03                 ` Vivek Goyal
2016-07-13 17:40                   ` Russell King - ARM Linux
2016-07-13 18:22                     ` Vivek Goyal
2016-07-18 12:46                       ` Balbir Singh
2016-07-18 13:26                         ` Vivek Goyal
2016-07-18 13:38                           ` Vivek Goyal
2016-07-20  3:45                           ` Balbir Singh
2016-07-20  8:35                             ` Russell King - ARM Linux
2016-07-20 10:47                               ` Michael Ellerman
2016-07-20 11:12                               ` Arnd Bergmann
2016-07-20 15:50                                 ` Thiago Jung Bauermann
2016-07-20 12:46                               ` Vivek Goyal
2016-07-20 12:27                             ` Vivek Goyal
2016-07-12 23:41       ` Stewart Smith
2016-07-13 13:25         ` Vivek Goyal

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=20160712014201.11456-4-takahiro.akashi@linaro.org \
    --to=takahiro.akashi@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.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).