linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: kexec@lists.infradead.org, x86@kernel.org,
	linux-kernel@vger.kernel.org,
	Eric Biederman <ebiederm@xmission.com>,
	Dave Young <dyoung@redhat.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Mimi Zohar <zohar@linux.vnet.ibm.com>,
	Eric Richter <erichte@linux.vnet.ibm.com>,
	Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Subject: [PATCH 2/6] powerpc: kexec_file: Add buffer hand-over support for the next kernel
Date: Mon, 20 Jun 2016 22:44:32 -0300	[thread overview]
Message-ID: <1466473476-10104-3-git-send-email-bauerman@linux.vnet.ibm.com> (raw)
In-Reply-To: <1466473476-10104-1-git-send-email-bauerman@linux.vnet.ibm.com>

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-specific part.

Signed-off-by: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kexec.h       |  9 +++++
 arch/powerpc/kernel/kexec_elf_64.c     | 44 +++++++++++++++++++++++
 arch/powerpc/kernel/machine_kexec_64.c | 64 ++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)

diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index a46f5f45570c..9b1ff59bc188 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -55,6 +55,15 @@ typedef void (*crash_shutdown_t)(void);
 
 #ifdef CONFIG_KEXEC
 
+#ifdef CONFIG_KEXEC_FILE
+#define ARCH_HAS_KIMAGE_ARCH
+
+struct kimage_arch {
+	phys_addr_t handover_buffer_addr;
+	unsigned long handover_buffer_size;
+};
+#endif
+
 /*
  * This function is responsible for capturing register states if coming
  * via panic or invoking dump using sysrq-trigger.
diff --git a/arch/powerpc/kernel/kexec_elf_64.c b/arch/powerpc/kernel/kexec_elf_64.c
index 4e71595300ed..5d2b7036fee7 100644
--- a/arch/powerpc/kernel/kexec_elf_64.c
+++ b/arch/powerpc/kernel/kexec_elf_64.c
@@ -96,6 +96,46 @@ static int elf64_probe(const char *buf, unsigned long len)
 	return elf_check_arch(&ehdr)? 0 : -ENOEXEC;
 }
 
+static int setup_handover_buffer(struct kimage *image, void *fdt,
+				 int chosen_node)
+{
+	int ret;
+
+	if (image->arch.handover_buffer_addr) {
+		ret = fdt_setprop_u64(fdt, chosen_node,
+				      "linux,kexec-handover-buffer-start",
+				      image->arch.handover_buffer_addr);
+		if (ret < 0) {
+			pr_err("Error setting up the new device tree.\n");
+			return -EINVAL;
+		}
+
+		/* -end is the first address after the buffer. */
+		ret = fdt_setprop_u64(fdt, chosen_node,
+				      "linux,kexec-handover-buffer-end",
+				      image->arch.handover_buffer_addr +
+				      image->arch.handover_buffer_size);
+		if (ret < 0) {
+			pr_err("Error setting up the new device tree.\n");
+			return -EINVAL;
+		}
+
+		ret = fdt_add_mem_rsv(fdt, image->arch.handover_buffer_addr,
+				      image->arch.handover_buffer_size);
+		if (ret) {
+			pr_err("Error reserving kexec handover buffer: %s\n",
+			       fdt_strerror(ret));
+			return -EINVAL;
+		}
+
+		pr_debug("kexec handover buffer at 0x%llx, size = 0x%lx\n",
+			 image->arch.handover_buffer_addr,
+			 image->arch.handover_buffer_size);
+	}
+
+	return 0;
+}
+
 static bool find_debug_console(void *fdt, int chosen_node)
 {
 	int len;
@@ -494,6 +534,10 @@ void *elf64_load(struct kimage *image, char *kernel_buf,
 		}
 	}
 
+	ret = setup_handover_buffer(image, fdt, chosen_node);
+	if (ret)
+		goto out;
+
 	ret = fdt_setprop(fdt, chosen_node, "linux,booted-from-kexec", NULL, 0);
 	if (ret) {
 		pr_err("Error setting up the new device tree.\n");
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 43e8185ab6f7..c582abf726f5 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -19,6 +19,7 @@
 #include <linux/cpu.h>
 #include <linux/hardirq.h>
 #include <linux/memblock.h>
+#include <linux/libfdt.h>
 
 #include <asm/page.h>
 #include <asm/current.h>
@@ -481,6 +482,69 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
 	return image->fops->cleanup(image->image_loader_data);
 }
 
+bool kexec_can_hand_over_buffer(void)
+{
+	return true;
+}
+
+int arch_kexec_add_handover_buffer(struct kimage *image,
+				   unsigned long load_addr, unsigned long size)
+{
+	image->arch.handover_buffer_addr = load_addr;
+	image->arch.handover_buffer_size = size;
+
+	return 0;
+}
+
+int kexec_get_handover_buffer(void **addr, unsigned long *size)
+{
+	int chosen_node;
+	int startsz, endsz;
+	const void *startp, *endp;
+	unsigned long start_addr, end_addr;
+
+	chosen_node = fdt_path_offset(initial_boot_params, "/chosen");
+	if (chosen_node < 0) {
+		pr_err("Malformed device tree: /chosen not found.\n");
+		return -EINVAL;
+	}
+
+	startp = of_get_flat_dt_prop(chosen_node,
+				     "linux,kexec-handover-buffer-start",
+				     &startsz);
+	endp = of_get_flat_dt_prop(chosen_node,
+				   "linux,kexec-handover-buffer-end",
+				   &endsz);
+	if (!startp || !endp) {
+		pr_debug("kexec handover buffer not found in the device tree.\n");
+		return -ENOENT;
+	}
+
+	start_addr = of_read_number(startp, startsz/4);
+	end_addr = of_read_number(endp, endsz/4);
+
+	*addr =  __va(start_addr);
+	/* -end is the first address after the buffer. */
+	*size = end_addr - start_addr;
+
+	pr_debug("kexec handover buffer at %p, size = %lu\n", *addr, *size);
+
+	return 0;
+}
+
+int kexec_free_handover_buffer(void)
+{
+	int ret;
+	void *addr;
+	unsigned long size;
+
+	ret = kexec_get_handover_buffer(&addr, &size);
+	if (ret)
+		return ret;
+
+	return memblock_free((phys_addr_t) addr, size);
+}
+
 /**
  * arch_kexec_walk_mem - call func(data) for each unreserved memory block
  * @image_type:	kimage.type
-- 
1.9.1

  parent reply	other threads:[~2016-06-21  1:45 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-21  1:44 [PATCH 0/6] kexec_file: Add buffer hand-over for the next kernel Thiago Jung Bauermann
2016-06-21  1:44 ` [PATCH 1/6] kexec_file: Add buffer hand-over support " Thiago Jung Bauermann
2016-06-21  1:44 ` Thiago Jung Bauermann [this message]
2016-06-21  1:44 ` [PATCH 3/6] kexec_file: Allow skipping checksum calculation for some segments Thiago Jung Bauermann
2016-06-21  1:44 ` [PATCH 4/6] kexec_file: Add mechanism to update kexec segments Thiago Jung Bauermann
2016-06-21  1:44 ` [PATCH 5/6] kexec: Share logic to copy segment page contents Thiago Jung Bauermann
2016-06-21  1:44 ` [PATCH 6/6] IMA: Demonstration code for kexec buffer passing Thiago Jung Bauermann
2016-06-22  1:20 ` [PATCH 0/6] kexec_file: Add buffer hand-over for the next kernel Dave Young
2016-06-22 13:19   ` Mimi Zohar
2016-06-22 16:34   ` Thiago Jung Bauermann

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=1466473476-10104-3-git-send-email-bauerman@linux.vnet.ibm.com \
    --to=bauerman@linux.vnet.ibm.com \
    --cc=dyoung@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=erichte@linux.vnet.ibm.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=x86@kernel.org \
    --cc=zohar@linux.vnet.ibm.com \
    /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).