aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2014-10-06 11:57:43 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-10-09 03:14:16 -0400
commita62bc0739253939d6fce40d51d92412252a9bb55 (patch)
tree48247426a662b82c2bd8a4b28054f3b715f60e6d /drivers/s390
parent3585cb0280654acbc559a360a839c8d58bb0cb87 (diff)
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')
-rw-r--r--drivers/s390/char/zcore.c18
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 @@
28#include <asm/processor.h> 28#include <asm/processor.h>
29#include <asm/irqflags.h> 29#include <asm/irqflags.h>
30#include <asm/checksum.h> 30#include <asm/checksum.h>
31#include <asm/switch_to.h>
31#include "sclp.h" 32#include "sclp.h"
32 33
33#define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x) 34#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)
149 150
150static int __init init_cpu_info(enum arch_id arch) 151static int __init init_cpu_info(enum arch_id arch)
151{ 152{
152 struct save_area *sa; 153 struct save_area_ext *sa_ext;
153 154
154 /* get info for boot cpu from lowcore, stored in the HSA */ 155 /* get info for boot cpu from lowcore, stored in the HSA */
155 156
156 sa = dump_save_area_create(0); 157 sa_ext = dump_save_area_create(0);
157 if (!sa) 158 if (!sa_ext)
158 return -ENOMEM; 159 return -ENOMEM;
159 if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) { 160 if (memcpy_hsa_kernel(&sa_ext->sa, sys_info.sa_base,
161 sys_info.sa_size) < 0) {
160 TRACE("could not copy from HSA\n"); 162 TRACE("could not copy from HSA\n");
161 kfree(sa); 163 kfree(sa_ext);
162 return -EIO; 164 return -EIO;
163 } 165 }
166 if (MACHINE_HAS_VX)
167 save_vx_regs_safe(sa_ext->vx_regs);
164 return 0; 168 return 0;
165} 169}
166 170
@@ -258,7 +262,7 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
258 unsigned long sa_start, sa_end; /* save area range */ 262 unsigned long sa_start, sa_end; /* save area range */
259 unsigned long prefix; 263 unsigned long prefix;
260 unsigned long sa_off, len, buf_off; 264 unsigned long sa_off, len, buf_off;
261 struct save_area *save_area = dump_save_areas.areas[i]; 265 struct save_area *save_area = &dump_save_areas.areas[i]->sa;
262 266
263 prefix = save_area->pref_reg; 267 prefix = save_area->pref_reg;
264 sa_start = prefix + sys_info.sa_base; 268 sa_start = prefix + sys_info.sa_base;
@@ -612,7 +616,7 @@ static void __init zcore_header_init(int arch, struct zcore_header *hdr,
612 hdr->tod = get_tod_clock(); 616 hdr->tod = get_tod_clock();
613 get_cpu_id(&hdr->cpu_id); 617 get_cpu_id(&hdr->cpu_id);
614 for (i = 0; i < dump_save_areas.count; i++) { 618 for (i = 0; i < dump_save_areas.count; i++) {
615 prefix = dump_save_areas.areas[i]->pref_reg; 619 prefix = dump_save_areas.areas[i]->sa.pref_reg;
616 hdr->real_cpu_cnt++; 620 hdr->real_cpu_cnt++;
617 if (!prefix) 621 if (!prefix)
618 continue; 622 continue;