Commit bbfed511 authored by Martin Schwidefsky's avatar Martin Schwidefsky

s390/zcore: copy vector registers into the image data

The /sys/kernel/debug/zcore/mem interface delivers the memory of the
old system with the CPU registers stored to the assigned locations in
each prefix page.

For the vector registers the prefix page of each CPU has an address of
a 1024 byte save area at 0x11b0. But the /sys/kernel/debug/zcore/mem
interface fails copy the vector registers saved at boot of the zfcpdump
kernel into the dump image.

Copy the saved vector registers of a CPU to the outout buffer if the
memory area that is read via /sys/kernel/debug/zcore/mem intersects
with the vector register save area of this CPU.
Acked-by: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 4c5b03b6
...@@ -35,6 +35,7 @@ struct save_area { ...@@ -35,6 +35,7 @@ struct save_area {
struct save_area_ext { struct save_area_ext {
struct save_area sa; struct save_area sa;
__vector128 vx_regs[32]; __vector128 vx_regs[32];
u64 vx_sa_addr;
}; };
struct _lowcore { struct _lowcore {
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/irqflags.h> #include <asm/irqflags.h>
#include <asm/checksum.h> #include <asm/checksum.h>
#include <asm/os_info.h>
#include <asm/switch_to.h> #include <asm/switch_to.h>
#include "sclp.h" #include "sclp.h"
...@@ -151,6 +152,9 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) ...@@ -151,6 +152,9 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
static int __init init_cpu_info(enum arch_id arch) static int __init init_cpu_info(enum arch_id arch)
{ {
struct save_area_ext *sa_ext; struct save_area_ext *sa_ext;
struct _lowcore *lc;
void *ptr;
int i;
/* get info for boot cpu from lowcore, stored in the HSA */ /* get info for boot cpu from lowcore, stored in the HSA */
...@@ -162,8 +166,18 @@ static int __init init_cpu_info(enum arch_id arch) ...@@ -162,8 +166,18 @@ static int __init init_cpu_info(enum arch_id arch)
TRACE("could not copy from HSA\n"); TRACE("could not copy from HSA\n");
return -EIO; return -EIO;
} }
if (MACHINE_HAS_VX) if (!MACHINE_HAS_VX)
return 0;
save_vx_regs_safe(sa_ext->vx_regs); save_vx_regs_safe(sa_ext->vx_regs);
/* Get address of the vector register save area for each CPU */
for (i = 0; i < dump_save_areas.count; i++) {
sa_ext = dump_save_areas.areas[i];
lc = (struct _lowcore *)(unsigned long) sa_ext->sa.pref_reg;
ptr = &lc->vector_save_area_addr;
copy_from_oldmem(&sa_ext->vx_sa_addr, ptr,
sizeof(sa_ext->vx_sa_addr));
}
return 0; return 0;
} }
...@@ -245,6 +259,8 @@ static int copy_lc(void __user *buf, void *sa, int sa_off, int len) ...@@ -245,6 +259,8 @@ static int copy_lc(void __user *buf, void *sa, int sa_off, int len)
*/ */
static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
{ {
struct save_area_ext *sa_ext;
struct save_area *sa;
unsigned long end; unsigned long end;
int i; int i;
...@@ -255,16 +271,35 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) ...@@ -255,16 +271,35 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
for (i = 0; i < dump_save_areas.count; i++) { for (i = 0; i < dump_save_areas.count; i++) {
unsigned long cp_start, cp_end; /* copy range */ unsigned long cp_start, cp_end; /* copy range */
unsigned long sa_start, sa_end; /* save area range */ unsigned long sa_start, sa_end; /* save area range */
unsigned long prefix;
unsigned long sa_off, len, buf_off; unsigned long sa_off, len, buf_off;
struct save_area *save_area = &dump_save_areas.areas[i]->sa;
prefix = save_area->pref_reg; sa_ext = dump_save_areas.areas[i];
sa_start = prefix + sys_info.sa_base; sa = &sa_ext->sa;
sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
/* Copy the 512 bytes lowcore save area 0x1200 - 0x1400 */
sa_start = sa->pref_reg + sys_info.sa_base;
sa_end = sa_start + sys_info.sa_size;
if ((end < sa_start) || (start > sa_end)) if (end >= sa_start && start < sa_end) {
cp_start = max(start, sa_start);
cp_end = min(end, sa_end);
buf_off = cp_start - start;
sa_off = cp_start - sa_start;
len = cp_end - cp_start;
TRACE("copy_lc: %lx-%lx\n", cp_start, cp_end);
if (copy_lc(buf + buf_off, sa, sa_off, len))
return -EFAULT;
}
if (!MACHINE_HAS_VX)
continue; continue;
/* Copy the 512 bytes vector save area */
sa_start = sa_ext->vx_sa_addr & -1024UL;
sa_end = sa_start + 512;
if (end >= sa_start && start < sa_end) {
cp_start = max(start, sa_start); cp_start = max(start, sa_start);
cp_end = min(end, sa_end); cp_end = min(end, sa_end);
...@@ -272,10 +307,13 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) ...@@ -272,10 +307,13 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
sa_off = cp_start - sa_start; sa_off = cp_start - sa_start;
len = cp_end - cp_start; len = cp_end - cp_start;
TRACE("copy_lc for: %lx\n", start); TRACE("copy vxrs: %lx-%lx\n", cp_start, cp_end);
if (copy_lc(buf + buf_off, save_area, sa_off, len)) if (copy_to_user(buf + buf_off,
(void *) &sa_ext->vx_regs + sa_off,
len))
return -EFAULT; return -EFAULT;
} }
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment