----- Original Message ----- > Hi Dave, > > On Wed, 17 Dec 2014 13:33:50 -0500 (EST) > Dave Anderson <anderson@xxxxxxxxxx> wrote: > > [snip] > > > From your example, I presume that this is only applicable to the active > > tasks? > > Correct. > > > 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).", > > > > Yes, this makes sense. Here the updated patch: Hi Mike. OK this looks good. In cmd_bt() I made the option s390x-only, and touched up the error message if it's attempted on a live system. Queued for crash-7.1.0: https://github.com/crash-utility/crash/commit/e30594ebeacd4a8e0d6c416123f204adf873bf9f Thanks, Dave > --- > [PATCH] crash: s390x: Add vector register support > > 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. > > This patch also adds the new -A option to the "bt" command. This > option produces almost the same output as the -a option, but in > addition also the new vector registers for all active tasks > are shown. This is done because for normal debugging using "bt -a" > 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 > 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@xxxxxxxxxxxxxxxxxx> > --- > defs.h | 1 > help.c | 1 > kernel.c | 5 +-- > netdump.c | 6 +++ > netdump.h | 14 ++++++++ > s390x.c | 100 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 6 files changed, 125 insertions(+), 2 deletions(-) > > --- 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 same as -a, but also displays vector registers (S390X only).", > " -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,13 +2003,12 @@ 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 'F': > if (bt->flags & BT_FULL_SYM_SLAB) > bt->flags |= BT_FULL_SYM_SLAB2; > @@ -2158,6 +2157,8 @@ cmd_bt(void) > } > break; > > + case 'A': > + bt->flags |= BT_SHOW_ALL_REGS; /* FALLTHROUGH */ > case 'a': > active++; > break; > --- 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility