diff options
author | Michael Holzheu <holzheu@linux.vnet.ibm.com> | 2014-10-06 19:57:43 +0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-10-09 11:14:16 +0400 |
commit | a62bc0739253939d6fce40d51d92412252a9bb55 (patch) | |
tree | 48247426a662b82c2bd8a4b28054f3b715f60e6d /drivers/s390/char | |
parent | 3585cb0280654acbc559a360a839c8d58bb0cb87 (diff) | |
download | linux-a62bc0739253939d6fce40d51d92412252a9bb55.tar.xz |
s390/kdump: add support for vector extension
With this patch for kdump the s390 vector registers are stored into the
prepared save areas in the old kernel and into the REGSET_VX_LOW and
REGSET_VX_HIGH ELF notes for /proc/vmcore in the new kernel.
The NT_S390_VXRS_LOW note contains the lower halves of the first 16 vector
registers 0-15. The higher halves are stored in the floating point register
ELF note. The NT_S390_VXRS_HIGH contains the full vector registers 16-31.
The kernel provides a save area for storing vector register in case of
machine checks. A pointer to this save are is stored in the CPU lowcore
at offset 0x11b0. This save area is also used to save the registers for
kdump. In case of a dumped crashed kdump those areas are used to extract
the registers of the production system.
The vector registers for remote CPUs are stored using the "store additional
status at address" SIGP. For the dump CPU the vector registers are stored
with the VSTM instruction.
With this patch also zfcpdump stores the vector registers.
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/zcore.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 1884653e4472..efcf48481c5f 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -28,6 +28,7 @@ #include <asm/processor.h> #include <asm/irqflags.h> #include <asm/checksum.h> +#include <asm/switch_to.h> #include "sclp.h" #define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x) @@ -149,18 +150,21 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) static int __init init_cpu_info(enum arch_id arch) { - struct save_area *sa; + struct save_area_ext *sa_ext; /* get info for boot cpu from lowcore, stored in the HSA */ - sa = dump_save_area_create(0); - if (!sa) + sa_ext = dump_save_area_create(0); + if (!sa_ext) return -ENOMEM; - if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) { + if (memcpy_hsa_kernel(&sa_ext->sa, sys_info.sa_base, + sys_info.sa_size) < 0) { TRACE("could not copy from HSA\n"); - kfree(sa); + kfree(sa_ext); return -EIO; } + if (MACHINE_HAS_VX) + save_vx_regs_safe(sa_ext->vx_regs); return 0; } @@ -258,7 +262,7 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) unsigned long sa_start, sa_end; /* save area range */ unsigned long prefix; unsigned long sa_off, len, buf_off; - struct save_area *save_area = dump_save_areas.areas[i]; + struct save_area *save_area = &dump_save_areas.areas[i]->sa; prefix = save_area->pref_reg; sa_start = prefix + sys_info.sa_base; @@ -612,7 +616,7 @@ static void __init zcore_header_init(int arch, struct zcore_header *hdr, hdr->tod = get_tod_clock(); get_cpu_id(&hdr->cpu_id); for (i = 0; i < dump_save_areas.count; i++) { - prefix = dump_save_areas.areas[i]->pref_reg; + prefix = dump_save_areas.areas[i]->sa.pref_reg; hdr->real_cpu_cnt++; if (!prefix) continue; |