----- 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@xxxxxxxxxxxxxxxxxx> > > --- > > 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@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility