[Crash-utility] [PATCH] crash: s390x: Add vector register support
Dave Anderson
anderson at redhat.com
Wed Dec 17 18:33:50 UTC 2014
----- Original Message -----
>
>
> ----- Original Message -----
> > Hello Dave,
> >
> > This patch adds support for the new s390x vector registers.
> > For ELF dumps the registers are taken from the VX ELF notes, for
> > s390 dumps the registers are taken from memory. The kernel stores
> > a pointer the save area in the CPU lowcores at offset 0x11b0.
>
> Just a thought -- might this be more applicable to "help -r", which
> is where per-cpu register dumps are normally done?
But if not...
>From your example, I presume that this is only applicable to the active
tasks? So instead of using the somewhat-strange "bt -a -A" construct,
maybe you could just enter "bt -A" to accomplish the same result?
So cmd_bt() would have:
case 'A':
bt->flags |= BT_SHOW_ALL_REGS; /* FALLTHROUGH */
case 'a':
active++;
break;
and the help page would have something like:
-a displays the stack traces of the active task on each CPU.",
(only applicable to crash dumps)",
-A same as -a, but also displays vector registers (S390X only).",
Dave
>
> Dave
>
> >
> > This patch also adds a new -A option to the "bt" command. The
> > new vector registers are only shown when this option is specified.
> > This is done because for normal degugging we do not want to
> > pollute the bt output with the large vector register output (512 byte).
> >
> > The following shows an output example:
> >
> > crash> bt -a -A
> > PID: 2387 TASK: 1785a5e8 CPU: 0 COMMAND: "bash"
> > LOWCORE INFO:
> > -psw : 0x0400d00180000000 0x0000000000112aa0
> > -function : store_status at 112aa0
> > -prefix : 0x1fffc000
> > -cpu timer: 0x7ffffff3 0x0066ef81
> > -clock cmp: 0x0066ef81 0000000000
> > -general registers:
> > 000000000000000000 0x0400c00180000000
> > ....
> > - vector registers:
> > 0x404b000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x404b000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> > 0x0000000000000000 0x0000000000000000
> >
> > Signed-off-by: Michael Holzheu <holzheu at linux.vnet.ibm.com>
> > ---
> > defs.h | 1
> > help.c | 1
> > kernel.c | 5 ++-
> > netdump.c | 6 +++
> > netdump.h | 14 ++++++++
> > s390x.c | 100
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 6 files changed, 126 insertions(+), 1 deletion(-)
> >
> > --- a/defs.h
> > +++ b/defs.h
> > @@ -4966,6 +4966,7 @@ ulong cpu_map_addr(const char *type);
> > #define BT_FULL_SYM_SLAB2 (0x400000000000ULL)
> > #define BT_EFRAME_TARGET (0x800000000000ULL)
> > #define BT_CPUMASK (0x1000000000000ULL)
> > +#define BT_SHOW_ALL_REGS (0x2000000000000ULL)
> > #define BT_SYMBOL_OFFSET (BT_SYMBOLIC_ARGS)
> >
> > #define BT_REF_HEXVAL (0x1)
> > --- a/help.c
> > +++ b/help.c
> > @@ -1742,6 +1742,7 @@ char *help_bt[] = {
> > " trace of the current context will be displayed.\n",
> > " -a displays the stack traces of the active task on each CPU.",
> > " (only applicable to crash dumps)",
> > +" -A displays all available CPU registers.",
> > " -c cpu display the stack trace of the active task on one or more
> > CPUs,",
> > " which can be specified using the format \"3\", \"1,8,9\",
> > \"1-23\",",
> > " or \"1,8,9-14\". (only applicable to crash dumps)",
> > --- a/kernel.c
> > +++ b/kernel.c
> > @@ -2003,12 +2003,15 @@ cmd_bt(void)
> > if (kt->flags & USE_OLD_BT)
> > bt->flags |= BT_OLD_BACK_TRACE;
> >
> > - while ((c = getopt(argcnt, args, "D:fFI:S:c:aloreEgstTdxR:O")) !=
> > EOF) {
> > + while ((c = getopt(argcnt, args, "D:fFI:S:c:aAloreEgstTdxR:O")) != EOF) {
> > switch (c)
> > {
> > case 'f':
> > bt->flags |= BT_FULL;
> > break;
> > + case 'A':
> > + bt->flags |= BT_SHOW_ALL_REGS;
> > + break;
> >
> > case 'F':
> > if (bt->flags & BT_FULL_SYM_SLAB)
> > --- a/netdump.c
> > +++ b/netdump.c
> > @@ -2086,6 +2086,12 @@ dump_Elf64_Nhdr(Elf64_Off offset, int st
> > case NT_S390_PREFIX:
> > netdump_print("(NT_S390_PREFIX)\n");
> > break;
> > + case NT_S390_VXRS_LOW:
> > + netdump_print("(NT_S390_VXRS_LOW)\n");
> > + break;
> > + case NT_S390_VXRS_HIGH:
> > + netdump_print("(NT_S390_VXRS_HIGH)\n");
> > + break;
> > case NT_TASKSTRUCT:
> > netdump_print("(NT_TASKSTRUCT)\n");
> > if (STRNEQ(buf, "SNAP"))
> > --- a/netdump.h
> > +++ b/netdump.h
> > @@ -169,6 +169,20 @@ struct xen_kdump_data {
> > #define NT_S390_PREFIX 0x305
> > #endif
> >
> > +/*
> > + * S390 vector registers 0-15 upper half note (16 * u64)
> > + */
> > +#ifndef NT_S390_VXRS_LOW
> > +#define NT_S390_VXRS_LOW 0x309
> > +#endif
> > +
> > +/*
> > + * S390 vector registers 16-31 note (16 * u128)
> > + */
> > +#ifndef NT_S390_VXRS_HIGH
> > +#define NT_S390_VXRS_HIGH 0x30a
> > +#endif
> > +
> > #define MAX_KCORE_ELF_HEADER_SIZE (32768)
> >
> > struct proc_kcore_data {
> > --- a/s390x.c
> > +++ b/s390x.c
> > @@ -41,6 +41,7 @@
> > #define KERNEL_STACK_SIZE STACKSIZE() // can be 8192 or 16384
> >
> > #define LOWCORE_SIZE 8192
> > +#define VX_SA_SIZE (32 * 16)
> >
> > #define S390X_PSW_MASK_PSTATE 0x0001000000000000UL
> >
> > @@ -72,6 +73,11 @@ struct s390x_nt_fpregset {
> > uint64_t fprs[16];
> > } __attribute__ ((packed));
> >
> > +struct s390x_vxrs {
> > + uint64_t low;
> > + uint64_t high;
> > +} __attribute__ ((packed));
> > +
> > /*
> > * s390x CPU info
> > */
> > @@ -87,6 +93,8 @@ struct s390x_cpu
> > uint64_t timer;
> > uint64_t todcmp;
> > uint32_t todpreg;
> > + uint64_t vxrs_low[16];
> > + struct s390x_vxrs vxrs_high[16];
> > };
> >
> > /*
> > @@ -133,6 +141,27 @@ static unsigned long readmem_ul(unsigned
> > }
> >
> > /*
> > + * Print hex data
> > + */
> > +static void print_hex_buf(void *buf, int len, int cols, char *tag)
> > +{
> > + int j, first = 1;
> > +
> > + for (j = 0; j < len; j += 8) {
> > + if (j % (cols * 8) == 0) {
> > + if (first)
> > + first = 0;
> > + else
> > + fprintf(fp, "\n");
> > + fprintf(fp, "%s", tag);
> > + }
> > + fprintf(fp, "%#018lx ", *((unsigned long *)(buf + j)));
> > + }
> > + if (len)
> > + fprintf(fp, "\n");
> > +}
> > +
> > +/*
> > * Initialize member offsets
> > */
> > static void s390x_offsets_init(void)
> > @@ -271,6 +300,16 @@ static void s390x_elf_nt_prefix_add(stru
> > memcpy(&cpu->prefix, desc, sizeof(cpu->prefix));
> > }
> >
> > +static void s390x_elf_nt_vxrs_low_add(struct s390x_cpu *cpu, void *desc)
> > +{
> > + memcpy(&cpu->vxrs_low, desc, sizeof(cpu->vxrs_low));
> > +}
> > +
> > +static void s390x_elf_nt_vxrs_high_add(struct s390x_cpu *cpu, void *desc)
> > +{
> > + memcpy(&cpu->vxrs_high, desc, sizeof(cpu->vxrs_high));
> > +}
> > +
> > static void *get_elf_note_desc(Elf64_Nhdr *note)
> > {
> > void *ptr = note;
> > @@ -315,6 +354,12 @@ static void s390x_elf_note_add(int elf_c
> > case NT_S390_PREFIX:
> > s390x_elf_nt_prefix_add(cpu, desc);
> > break;
> > + case NT_S390_VXRS_LOW:
> > + s390x_elf_nt_vxrs_low_add(cpu, desc);
> > + break;
> > + case NT_S390_VXRS_HIGH:
> > + s390x_elf_nt_vxrs_high_add(cpu, desc);
> > + break;
> > }
> > }
> >
> > @@ -916,6 +961,59 @@ s390x_get_lowcore(struct bt_info *bt, ch
> > }
> >
> > /*
> > + * Copy VX registers out of s390x cpu
> > + */
> > +static void vx_copy(void *buf, struct s390x_cpu *s390x_cpu)
> > +{
> > + char *_buf = buf;
> > + int i;
> > +
> > + for (i = 0; i < 16; i++) {
> > + memcpy(&_buf[i * 16], &s390x_cpu->fprs[i], 8);
> > + memcpy(&_buf[i * 16 + 8], &s390x_cpu->vxrs_low[i], 8);
> > + }
> > + memcpy(&_buf[16 * 16], &s390x_cpu->vxrs_high[0], 16 * 16);
> > +}
> > +
> > +/*
> > + * Check if VX registers are available
> > + */
> > +static int has_vx_regs(char *lowcore)
> > +{
> > + unsigned long addr = *((uint64_t *)(lowcore + 0x11b0));
> > +
> > + if (addr == 0 || addr % 1024)
> > + return 0;
> > + return 1;
> > +}
> > +
> > +/*
> > + * Print vector registers for cpu
> > + */
> > +static void
> > +s390x_print_vx_sa(struct bt_info *bt, char *lc)
> > +{
> > + char vx_sa[VX_SA_SIZE];
> > + uint64_t addr;
> > +
> > + if (!(bt->flags & BT_SHOW_ALL_REGS))
> > + return;
> > + if (!has_vx_regs(lc))
> > + return;
> > + if (!s390x_cpu_vec) {
> > + /* Pointer to save area */
> > + addr = *((uint64_t *)(lc + 0x11b0));
> > + readmem(addr, KVADDR, vx_sa, sizeof(vx_sa), "vx_sa",
> > + FAULT_ON_ERROR);
> > + } else {
> > + /* Get data from s390x cpu */
> > + vx_copy(vx_sa, s390x_cpu_get(bt));
> > + }
> > + fprintf(fp, " -vector registers:\n");
> > + print_hex_buf(vx_sa, sizeof(vx_sa), 2, " ");
> > +}
> > +
> > +/*
> > * Get stack address for interrupt stack using the pcpu array
> > */
> > static unsigned long get_int_stack_pcpu(char *stack_name, int cpu)
> > @@ -1180,9 +1278,11 @@ static void s390x_back_trace_cmd(struct
> > if (psw_flags & S390X_PSW_MASK_PSTATE) {
> > fprintf(fp,"Task runs in userspace\n");
> > s390x_print_lowcore(lowcore,bt,0);
> > + s390x_print_vx_sa(bt, lowcore);
> > return;
> > }
> > s390x_print_lowcore(lowcore,bt,1);
> > + s390x_print_vx_sa(bt, lowcore);
> > fprintf(fp,"\n");
> > if (symbol_exists("restart_stack")) {
> > get_int_stack("restart_stack",
> >
>
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
>
More information about the Crash-utility
mailing list