[PATCH 08/11] ppc64/kexec_file: setup the stack for purgatory

From: Hari Bathini
Date: Fri Jun 26 2020 - 15:06:14 EST


To avoid any weird errors, the purgatory should run with its own
stack. Set one up by adding the stack buffer to .data section of
the purgatory.

Signed-off-by: Hari Bathini <hbathini@xxxxxxxxxxxxx>
---
arch/powerpc/include/asm/kexec.h | 4 ++++
arch/powerpc/kexec/file_load_64.c | 14 +++++++++++++-
arch/powerpc/purgatory/trampoline_64.S | 15 +++++++++++++++
3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index bf47a01..e78cd0a 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -45,6 +45,10 @@
#define KEXEC_ARCH KEXEC_ARCH_PPC
#endif

+#ifdef CONFIG_KEXEC_FILE
+#define KEXEC_PURGATORY_STACK_SIZE 16384 /* 16KB stack size */
+#endif
+
#define KEXEC_STATE_NONE 0
#define KEXEC_STATE_IRQS_OFF 1
#define KEXEC_STATE_REAL_MODE 2
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index 4430336..8e66c28 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -878,7 +878,8 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
const void *fdt, unsigned long kernel_load_addr,
unsigned long fdt_load_addr)
{
- uint64_t toc_ptr;
+ uint64_t toc_ptr, stack_top;
+ void *stack_buf;
int ret;

ret = setup_purgatory(image, slave_code, fdt, kernel_load_addr,
@@ -901,6 +902,17 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
goto out;
}

+ /* Setup the stack top */
+ stack_buf = kexec_purgatory_get_symbol_addr(image, "stack_buf");
+ if (!stack_buf)
+ goto out;
+
+ stack_top = (u64)stack_buf + KEXEC_PURGATORY_STACK_SIZE;
+ ret = kexec_purgatory_get_set_symbol(image, "stack", &stack_top,
+ sizeof(stack_top), false);
+ if (ret)
+ goto out;
+
/* Setup the TOC pointer */
toc_ptr = get_toc_ptr(image->purgatory_info.ehdr);
ret = kexec_purgatory_get_set_symbol(image, "my_toc", &toc_ptr,
diff --git a/arch/powerpc/purgatory/trampoline_64.S b/arch/powerpc/purgatory/trampoline_64.S
index 7b4a5f7..80615b4 100644
--- a/arch/powerpc/purgatory/trampoline_64.S
+++ b/arch/powerpc/purgatory/trampoline_64.S
@@ -9,6 +9,7 @@
* Copyright (C) 2013, Anton Blanchard, IBM Corporation
*/

+#include <asm/kexec.h>
#include <asm/asm-compat.h>

.machine ppc64
@@ -53,6 +54,8 @@ master:

ld %r2,(my_toc - 0b)(%r18) /* setup toc */

+ ld %r1,(stack - 0b)(%r18) /* setup stack */
+
/* load device-tree address */
ld %r3, (dt_offset - 0b)(%r18)
mr %r16,%r3 /* save dt address in reg16 */
@@ -111,6 +114,12 @@ my_toc:
.8byte 0x0
.size my_toc, . - my_toc

+ .balign 8
+ .globl stack
+stack:
+ .8byte 0x0
+ .size stack, . - stack
+
.data
.balign 8
.globl purgatory_sha256_digest
@@ -123,3 +132,9 @@ purgatory_sha256_digest:
purgatory_sha_regions:
.skip 8 * 2 * 16
.size purgatory_sha_regions, . - purgatory_sha_regions
+
+ .balign 8
+.globl stack_buf
+stack_buf:
+ .skip KEXEC_PURGATORY_STACK_SIZE
+ .size stack_buf, . - stack_buf