diff options
author | Michael Holzheu <holzheu@linux.vnet.ibm.com> | 2011-08-19 15:09:50 +0200 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2011-08-20 18:02:29 +0900 |
commit | d866fa444cc47097c07b3d31c494fdacd977f6d8 (patch) | |
tree | 6c902b0b94b1f8fa02459e52c3af269c6a4066cd /purgatory | |
parent | 7c7caf11813cf9993201285886ba9661b3de2d18 (diff) | |
download | kexec-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/Makefile | 5 | ||||
-rw-r--r-- | purgatory/arch/s390/console-s390.c | 14 | ||||
-rw-r--r-- | purgatory/arch/s390/purgatory-s390.c | 93 | ||||
-rw-r--r-- | purgatory/arch/s390/setup-s390.S | 33 |
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 |