[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1471058305-30198-2-git-send-email-bauerman@linux.vnet.ibm.com>
Date: Sat, 13 Aug 2016 00:18:20 -0300
From: Thiago Jung Bauermann <bauerman@...ux.vnet.ibm.com>
To: kexec@...ts.infradead.org
Cc: linux-security-module@...r.kernel.org,
linux-ima-devel@...ts.sourceforge.net,
linuxppc-dev@...ts.ozlabs.org, linux-kernel@...r.kernel.org,
x86@...nel.org, Eric Biederman <ebiederm@...ssion.com>,
Dave Young <dyoung@...hat.com>,
Vivek Goyal <vgoyal@...hat.com>, Baoquan He <bhe@...hat.com>,
Michael Ellerman <mpe@...erman.id.au>,
Benjamin Herrenschmidt <benh@...nel.crashing.org>,
Paul Mackerras <paulus@...ba.org>,
Stewart Smith <stewart@...ux.vnet.ibm.com>,
Samuel Mendoza-Jonas <sam@...dozajonas.com>,
Mimi Zohar <zohar@...ux.vnet.ibm.com>,
Eric Richter <erichte@...ux.vnet.ibm.com>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>,
"H. Peter Anvin" <hpa@...or.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Petko Manolov <petkan@...-labs.com>,
David Laight <David.Laight@...LAB.COM>,
Balbir Singh <bsingharora@...il.com>,
Thiago Jung Bauermann <bauerman@...ux.vnet.ibm.com>
Subject: [PATCH v2 1/6] kexec_file: Add buffer hand-over support for the next kernel
The buffer hand-over mechanism allows the currently running kernel to pass
data to kernel that will be kexec'd via a kexec segment. The second kernel
can check whether the previous kernel sent data and retrieve it.
This is the architecture-independent part of the feature.
Signed-off-by: Thiago Jung Bauermann <bauerman@...ux.vnet.ibm.com>
---
include/linux/kexec.h | 29 ++++++++++++++++++++++
kernel/kexec_file.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index ceccc5856aab..4559a1a01b0a 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -388,6 +388,35 @@ static inline void *boot_phys_to_virt(unsigned long entry)
return phys_to_virt(boot_phys_to_phys(entry));
}
+#ifdef CONFIG_KEXEC_FILE
+bool __weak kexec_can_hand_over_buffer(void);
+int __weak arch_kexec_add_handover_buffer(struct kimage *image,
+ unsigned long load_addr,
+ unsigned long size);
+int kexec_add_handover_buffer(struct kexec_buf *kbuf);
+int __weak kexec_get_handover_buffer(void **addr, unsigned long *size);
+int __weak kexec_free_handover_buffer(void);
+#else
+static inline bool kexec_can_hand_over_buffer(void)
+{
+ return false;
+}
+
+static inline int kexec_add_handover_buffer(struct kexec_buf *kbuf)
+{
+ return -ENOTSUPP;
+}
+
+static inline int kexec_get_handover_buffer(void **addr, unsigned long *size)
+{
+ return -ENOTSUPP;
+}
+
+static inline int kexec_free_handover_buffer(void)
+{
+ return -ENOTSUPP;
+}
+#endif /* CONFIG_KEXEC_FILE */
#else /* !CONFIG_KEXEC_CORE */
struct pt_regs;
struct task_struct;
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 772cb491715e..c8418d62e2fc 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -135,6 +135,74 @@ int __weak arch_kexec_verify_buffer(enum kexec_file_type type, const void *buf,
return -EINVAL;
}
+/**
+ * kexec_can_hand_over_buffer - can we pass data to the kexec'd kernel?
+ */
+bool __weak kexec_can_hand_over_buffer(void)
+{
+ return false;
+}
+
+/**
+ * arch_kexec_add_handover_buffer - do arch-specific steps to handover buffer
+ *
+ * Architectures should use this function to pass on the handover buffer
+ * information to the next kernel.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int __weak arch_kexec_add_handover_buffer(struct kimage *image,
+ unsigned long load_addr,
+ unsigned long size)
+{
+ return -ENOTSUPP;
+}
+
+/**
+ * kexec_add_handover_buffer - add buffer to be used by the next kernel
+ * @kbuf: Buffer contents and memory parameters.
+ *
+ * This function assumes that kexec_mutex is held.
+ * On successful return, @kbuf->mem will have the physical address of
+ * the buffer in the next kernel.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int kexec_add_handover_buffer(struct kexec_buf *kbuf)
+{
+ int ret;
+
+ if (!kexec_can_hand_over_buffer())
+ return -ENOTSUPP;
+
+ ret = kexec_add_buffer(kbuf);
+ if (ret)
+ return ret;
+
+ return arch_kexec_add_handover_buffer(kbuf->image, kbuf->mem,
+ kbuf->memsz);
+}
+
+/**
+ * kexec_get_handover_buffer - get the handover buffer from the previous kernel
+ * @addr: On successful return, set to point to the buffer contents.
+ * @size: On successful return, set to the buffer size.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int __weak kexec_get_handover_buffer(void **addr, unsigned long *size)
+{
+ return -ENOTSUPP;
+}
+
+/**
+ * kexec_free_handover_buffer - free memory used by the handover buffer
+ */
+int __weak kexec_free_handover_buffer(void)
+{
+ return -ENOTSUPP;
+}
+
/*
* In file mode list of segments is prepared by kernel. Copy relevant
* data from user space, do error checking, prepare segment list
--
1.9.1
Powered by blists - more mailing lists