summaryrefslogtreecommitdiffstats
path: root/purgatory
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2011-08-19 15:09:50 +0200
committerSimon Horman <horms@verge.net.au>2011-08-20 18:02:29 +0900
commitd866fa444cc47097c07b3d31c494fdacd977f6d8 (patch)
tree6c902b0b94b1f8fa02459e52c3af269c6a4066cd /purgatory
parent7c7caf11813cf9993201285886ba9661b3de2d18 (diff)
downloadkexec-tools-d866fa444cc47097c07b3d31c494fdacd977f6d8.tar.gz
kexec-tools: Add s390 kdump support
This patch adds kdump support for s390 to the kexec tool and enables the "--load-panic" option. When loading the kdump kernel and ramdisk we add the address of the crashkernel memory to the normal load address. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'purgatory')
-rw-r--r--purgatory/arch/s390/Makefile5
-rw-r--r--purgatory/arch/s390/console-s390.c14
-rw-r--r--purgatory/arch/s390/purgatory-s390.c93
-rw-r--r--purgatory/arch/s390/setup-s390.S33
4 files changed, 144 insertions, 1 deletions
diff --git a/purgatory/arch/s390/Makefile b/purgatory/arch/s390/Makefile
index d5f3068b..09749bd5 100644
--- a/purgatory/arch/s390/Makefile
+++ b/purgatory/arch/s390/Makefile
@@ -2,7 +2,10 @@
# Purgatory s390
#
-s390_PURGATORY_SRCS =
+s390_PURGATORY_EXTRA_CFLAGS += -fno-stack-protector
+s390_PURGATORY_SRCS += purgatory/arch/s390/console-s390.c
+s390_PURGATORY_SRCS += purgatory/arch/s390/setup-s390.S
+s390_PURGATORY_SRCS += purgatory/arch/s390/purgatory-s390.c
dist += purgatory/arch/s390/Makefile $(s390_PURGATORY_SRCS)
diff --git a/purgatory/arch/s390/console-s390.c b/purgatory/arch/s390/console-s390.c
new file mode 100644
index 00000000..fe4bd917
--- /dev/null
+++ b/purgatory/arch/s390/console-s390.c
@@ -0,0 +1,14 @@
+/*
+ * S390 console code (currently not implemented)
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <purgatory.h>
+#include "unused.h"
+
+void putchar(int UNUSED(ch))
+{
+}
diff --git a/purgatory/arch/s390/purgatory-s390.c b/purgatory/arch/s390/purgatory-s390.c
new file mode 100644
index 00000000..f438cf61
--- /dev/null
+++ b/purgatory/arch/s390/purgatory-s390.c
@@ -0,0 +1,93 @@
+/*
+ * S390 purgatory
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include "../../../kexec/kexec-sha256.h"
+
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+
+extern struct sha256_region sha256_regions[SHA256_REGIONS];
+
+unsigned long crash_base = (unsigned long) -1;
+unsigned long crash_size = (unsigned long) -1;
+
+/*
+ * Implement memcpy using the mvcle instruction
+ */
+static void memcpy_fast(void *target, void *src, unsigned long size)
+{
+ register unsigned long __target asm("2") = (unsigned long) target;
+ register unsigned long __size1 asm("3") = size;
+ register unsigned long __src asm("4") = (unsigned long) src;
+ register unsigned long __size2 asm("5") = size;
+
+ asm volatile (
+ "0: mvcle %0,%2,0\n"
+ " jo 0b\n"
+ : "+d" (__target), "+d" (__size1), "+d" (__src), "+d" (__size2)
+ :
+ : "cc", "memory"
+ );
+}
+
+/*
+ * Swap memory areas
+ */
+static void memswap(void *addr1, void *addr2, unsigned long size)
+{
+ unsigned long off, copy_len;
+ static char buf[1024];
+
+ for (off = 0; off < size; off += sizeof(buf)) {
+ copy_len = MIN(size - off, sizeof(buf));
+ memcpy_fast(buf, (void *) addr2 + off, copy_len);
+ memcpy_fast(addr2 + off, addr1 + off, copy_len);
+ memcpy_fast(addr1 + off, buf, copy_len);
+ }
+}
+
+/*
+ * Nothing to do
+ */
+void setup_arch(void)
+{
+}
+
+/*
+ * Do swap of [crash base - crash base + size] with [0 - crash size]
+ *
+ * We swap all kexec segments except of purgatory. The rest is copied
+ * from [0 - crash size] to [crash base - crash base + size].
+ * We use [0x2000 - 0x10000] for purgatory. This area is never used
+ * by s390 Linux kernels.
+ *
+ * This functions assumes that the sha256_regions[] is sorted.
+ */
+void post_verification_setup_arch(void)
+{
+ unsigned long start, len, last = crash_base + 0x10000;
+ struct sha256_region *ptr, *end;
+
+ end = &sha256_regions[sizeof(sha256_regions)/sizeof(sha256_regions[0])];
+ for (ptr = sha256_regions; ptr < end; ptr++) {
+ if (!ptr->start)
+ continue;
+ start = MAX(ptr->start, crash_base + 0x10000);
+ len = ptr->len - (start - ptr->start);
+ memcpy_fast((void *) last, (void *) last - crash_base,
+ start - last);
+ memswap((void *) start - crash_base, (void *) start, len);
+ last = start + len;
+ }
+ memcpy_fast((void *) last, (void *) last - crash_base,
+ crash_base + crash_size - last);
+ memcpy_fast((void *) crash_base, (void *) 0, 0x2000);
+}
diff --git a/purgatory/arch/s390/setup-s390.S b/purgatory/arch/s390/setup-s390.S
new file mode 100644
index 00000000..6db75fdd
--- /dev/null
+++ b/purgatory/arch/s390/setup-s390.S
@@ -0,0 +1,33 @@
+/*
+ * Purgatory setup code
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+ .text
+ .globl purgatory_start
+ .balign 16
+purgatory_start:
+#ifdef __s390x__
+ larl %r15,lstack_end
+ aghi %r15,-160
+ brasl %r14,purgatory
+ larl %r14,kdump_psw
+ lpswe 0(%r14)
+
+ .section ".data"
+ .balign 16
+kdump_psw:
+ .quad 0x0000000180000000
+ .quad 0x0000000000010010
+
+ .bss
+ .balign 4096
+lstack:
+ .skip 4096
+lstack_end:
+#else
+0: j 0
+#endif