----- "Michael Holzheu" <holzheu@xxxxxxxxxxxxxxxxxx> wrote: > Hi Dave, > > This patch fixes several bugs in the s390 stack backtrace code > * Add panic stack as second interrupt stack > * Fix printing of access registers (4 bytes instead of 8 bytes) > * Use u64 for s390x register 14 > * Fix interrupt stack handling for s390x (use 160 byte overhead > instead of 96) The patch looks OK upon first glance -- can you verify that it's absolutely backwards-compatible to earlier kernel versions? Thanks, Dave > --- > s390.c | 46 ++++++++++++++++++------------- > s390x.c | 94 > +++++++++++++++++++++++++++++++++++----------------------------- > 2 files changed, 79 insertions(+), 61 deletions(-) > > --- a/s390.c > +++ b/s390.c > @@ -37,7 +37,7 @@ > #define S390_PTE_INVALID_MASK 0x80000900 > #define S390_PTE_INVALID(x) ((x) & S390_PTE_INVALID_MASK) > > -#define ASYNC_STACK_SIZE STACKSIZE() // can be 4096 or 8192 > +#define INT_STACK_SIZE STACKSIZE() // can be 4096 or 8192 > #define KERNEL_STACK_SIZE STACKSIZE() // can be 4096 or 8192 > > #define LOWCORE_SIZE 4096 > @@ -570,20 +570,21 @@ s390_get_lowcore(int cpu, char* lowcore) > FAULT_ON_ERROR); > } > > -/* > - * read in the async stack > +/* > + * Read interrupt stack (either "async_stack" or "panic_stack"); > */ > -static void > -s390_get_async_stack(char* lowcore, char* async_stack, unsigned long* > start, unsigned long* end) > +static void s390_get_int_stack(char *stack_name, char* lc, char* > int_stack, > + unsigned long* start, unsigned long* end) > { > - unsigned long async_stack_ptr; > + unsigned long stack_addr; > > - async_stack_ptr = ULONG(lowcore + > - MEMBER_OFFSET("_lowcore","async_stack")); > - readmem(async_stack_ptr-ASYNC_STACK_SIZE,KVADDR, async_stack, > - ASYNC_STACK_SIZE, "async_stack", FAULT_ON_ERROR); > - *start=async_stack_ptr-ASYNC_STACK_SIZE; > - *end=async_stack_ptr; > + if (!MEMBER_EXISTS("_lowcore", stack_name)) > + return; > + stack_addr = ULONG(lc + MEMBER_OFFSET("_lowcore", stack_name)); > + readmem(stack_addr - INT_STACK_SIZE, KVADDR, int_stack, > + INT_STACK_SIZE, stack_name, FAULT_ON_ERROR); > + *start = stack_addr - INT_STACK_SIZE; > + *end = stack_addr; > } > > /* > @@ -593,16 +594,18 @@ static void > s390_back_trace_cmd(struct bt_info *bt) > { > char* stack; > - char async_stack[ASYNC_STACK_SIZE]; > + char async_stack[INT_STACK_SIZE]; > + char panic_stack[INT_STACK_SIZE]; > long ksp,backchain,old_backchain; > int i=0, r14_offset,bc_offset,r14, skip_first_frame=0; > - unsigned long async_start,async_end, stack_end, stack_start, > stack_base; > + unsigned long async_start = 0, async_end = 0; > + unsigned long panic_start = 0, panic_end = 0; > + unsigned long stack_end, stack_start, stack_base; > > if (bt->hp && bt->hp->eip) { > error(WARNING, > "instruction pointer argument ignored on this architecture!\n"); > } > - async_end = async_start = 0; > ksp = bt->stkptr; > > /* print lowcore and get async stack when task has cpu */ > @@ -622,9 +625,10 @@ s390_back_trace_cmd(struct bt_info *bt) > s390_print_lowcore(lowcore,bt,0); > return; > } > - > - s390_get_async_stack(lowcore,async_stack,&async_start, > - &async_end); > + s390_get_int_stack("async_stack", lowcore, async_stack, > + &async_start, &async_end); > + s390_get_int_stack("panic_stack", lowcore, panic_stack, > + &panic_start, &panic_end); > s390_print_lowcore(lowcore,bt,1); > fprintf(fp,"\n"); > skip_first_frame=1; > @@ -653,7 +657,7 @@ s390_back_trace_cmd(struct bt_info *bt) > unsigned long r14_stack_off; > int j; > > - /* Find stack: Either async stack or task stack */ > + /* Find stack: Either async, panic stack or task stack */ > if((backchain > stack_start) && (backchain < stack_end)){ > stack = bt->stackbuf; > stack_base = stack_start; > @@ -661,6 +665,10 @@ s390_back_trace_cmd(struct bt_info *bt) > && s390_has_cpu(bt)){ > stack = async_stack; > stack_base = async_start; > + } else if((backchain > panic_start) && (backchain < panic_end) > + && s390_has_cpu(bt)){ > + stack = panic_stack; > + stack_base = panic_start; > } else { > /* invalid stackframe */ > break; > --- a/s390x.c > +++ b/s390x.c > @@ -36,7 +36,7 @@ > #define S390X_PTE_INVALID_MASK 0x900ULL > #define S390X_PTE_INVALID(x) ((x) & S390X_PTE_INVALID_MASK) > > -#define ASYNC_STACK_SIZE STACKSIZE() // can be 8192 or 16384 > +#define INT_STACK_SIZE STACKSIZE() // can be 8192 or 16384 > #define KERNEL_STACK_SIZE STACKSIZE() // can be 8192 or 16384 > > #define LOWCORE_SIZE 8192 > @@ -803,19 +803,20 @@ s390x_get_lowcore(struct bt_info *bt, ch > } > > /* > - * read in the async stack > + * Read interrupt stack (either "async_stack" or "panic_stack"); > */ > -static void > -s390x_get_async_stack(char* lowcore, char* async_stack, unsigned > long* start, unsigned long* end) > +static void s390x_get_int_stack(char *stack_name, char* lc, char* > int_stack, > + unsigned long* start, unsigned long* end) > { > - unsigned long async_stack_ptr; > + unsigned long stack_addr; > > - async_stack_ptr = ULONG(lowcore + > - MEMBER_OFFSET("_lowcore","async_stack")); > - readmem(async_stack_ptr-ASYNC_STACK_SIZE,KVADDR, async_stack, > - ASYNC_STACK_SIZE, "async_stack", FAULT_ON_ERROR); > - *start=async_stack_ptr-ASYNC_STACK_SIZE; > - *end=async_stack_ptr; > + if (!MEMBER_EXISTS("_lowcore", stack_name)) > + return; > + stack_addr = ULONG(lc + MEMBER_OFFSET("_lowcore", stack_name)); > + readmem(stack_addr - INT_STACK_SIZE, KVADDR, int_stack, > + INT_STACK_SIZE, stack_name, FAULT_ON_ERROR); > + *start = stack_addr - INT_STACK_SIZE; > + *end = stack_addr; > } > > /* > @@ -825,11 +826,14 @@ static void > s390x_back_trace_cmd(struct bt_info *bt) > { > char* stack; > - char async_stack[ASYNC_STACK_SIZE]; > + char async_stack[INT_STACK_SIZE]; > + char panic_stack[INT_STACK_SIZE]; > long ksp,backchain,old_backchain; > - int i=0, r14_offset,bc_offset,r14, skip_first_frame=0; > + int i=0, r14_offset,bc_offset, skip_first_frame=0; > unsigned long async_start = 0, async_end = 0; > + unsigned long panic_start = 0, panic_end = 0; > unsigned long stack_end, stack_start, stack_base; > + unsigned long r14; > > if (bt->hp && bt->hp->eip) { > error(WARNING, > @@ -854,9 +858,10 @@ s390x_back_trace_cmd(struct bt_info *bt) > s390x_print_lowcore(lowcore,bt,0); > return; > } > - > - s390x_get_async_stack(lowcore,async_stack,&async_start, > - &async_end); > + s390x_get_int_stack("async_stack", lowcore, async_stack, > + &async_start, &async_end); > + s390x_get_int_stack("panic_stack", lowcore, panic_stack, > + &panic_start, &panic_end); > s390x_print_lowcore(lowcore,bt,1); > fprintf(fp,"\n"); > skip_first_frame=1; > @@ -885,7 +890,7 @@ s390x_back_trace_cmd(struct bt_info *bt) > unsigned long r14_stack_off; > int j; > > - /* Find stack: Either async stack or task stack */ > + /* Find stack: Either async, panic stack or task stack */ > if((backchain > stack_start) && (backchain < stack_end)){ > stack = bt->stackbuf; > stack_base = stack_start; > @@ -893,6 +898,10 @@ s390x_back_trace_cmd(struct bt_info *bt) > && s390x_has_cpu(bt)){ > stack = async_stack; > stack_base = async_start; > + } else if((backchain > panic_start) && (backchain < panic_end) > + && s390x_has_cpu(bt)){ > + stack = panic_stack; > + stack_base = panic_start; > } else { > /* invalid stackframe */ > break; > @@ -913,7 +922,7 @@ s390x_back_trace_cmd(struct bt_info *bt) > skip_first_frame=0; > } else { > fprintf(fp," #%i [%08lx] ",i,backchain); > - fprintf(fp,"%s at %x\n", closest_symbol(r14), r14); > + fprintf(fp,"%s at %lx\n", closest_symbol(r14), r14); > if (bt->flags & BT_LINE_NUMBERS) > s390x_dump_line_number(r14); > i++; > @@ -944,19 +953,20 @@ s390x_back_trace_cmd(struct bt_info *bt) > } > > /* Check for interrupt stackframe */ > - if((backchain == 0) && (stack == async_stack)){ > - unsigned long psw_flags,r15; > + if((backchain == 0) && > + (stack == async_stack || stack == panic_stack)) { > + int pt_regs_off = old_backchain - stack_base + 160; > + unsigned long psw_flags; > > - psw_flags = ULONG(&stack[old_backchain - stack_base > - +96 +MEMBER_OFFSET("pt_regs","psw")]); > + psw_flags = ULONG(&stack[pt_regs_off + > + MEMBER_OFFSET("pt_regs", "psw")]); > if(psw_flags & 0x1000000000000ULL){ > /* User psw: should not happen */ > break; > } > - r15 = ULONG(&stack[old_backchain - stack_base + > - 96 + MEMBER_OFFSET("pt_regs", > - "gprs") + 15 * S390X_WORD_SIZE]); > - backchain=r15; > + backchain = ULONG(&stack[pt_regs_off + > + MEMBER_OFFSET("pt_regs", "gprs") + > + 15 * S390X_WORD_SIZE]); > fprintf(fp," - Interrupt -\n"); > } > } while(backchain != 0); > @@ -1036,28 +1046,28 @@ s390x_print_lowcore(char* lc, struct bt_ > > fprintf(fp," -access registers:\n"); > ptr = lc + MEMBER_OFFSET("_lowcore","access_regs_save_area"); > - tmp[0]=ULONG(ptr); > - tmp[1]=ULONG(ptr + 4); > - tmp[2]=ULONG(ptr + 2 * 4); > - tmp[3]=ULONG(ptr + 3 * 4); > + tmp[0]=UINT(ptr); > + tmp[1]=UINT(ptr + 4); > + tmp[2]=UINT(ptr + 2 * 4); > + tmp[3]=UINT(ptr + 3 * 4); > fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", > tmp[0], tmp[1], tmp[2], tmp[3]); > - tmp[0]=ULONG(ptr + 4 * 4); > - tmp[1]=ULONG(ptr + 5 * 4); > - tmp[2]=ULONG(ptr + 6 * 4); > - tmp[3]=ULONG(ptr + 7 * 4); > + tmp[0]=UINT(ptr + 4 * 4); > + tmp[1]=UINT(ptr + 5 * 4); > + tmp[2]=UINT(ptr + 6 * 4); > + tmp[3]=UINT(ptr + 7 * 4); > fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", > tmp[0], tmp[1], tmp[2], tmp[3]); > - tmp[0]=ULONG(ptr + 8 * 4); > - tmp[1]=ULONG(ptr + 9 * 4); > - tmp[2]=ULONG(ptr + 10* 4); > - tmp[3]=ULONG(ptr + 11* 4); > + tmp[0]=UINT(ptr + 8 * 4); > + tmp[1]=UINT(ptr + 9 * 4); > + tmp[2]=UINT(ptr + 10 * 4); > + tmp[3]=UINT(ptr + 11 * 4); > fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", > tmp[0], tmp[1], tmp[2], tmp[3]); > - tmp[0]=ULONG(ptr + 12* 4); > - tmp[1]=ULONG(ptr + 13* 4); > - tmp[2]=ULONG(ptr + 14* 4); > - tmp[3]=ULONG(ptr + 15* 4); > + tmp[0]=UINT(ptr + 12 * 4); > + tmp[1]=UINT(ptr + 13 * 4); > + tmp[2]=UINT(ptr + 14 * 4); > + tmp[3]=UINT(ptr + 15 * 4); > fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", > tmp[0], tmp[1], tmp[2], tmp[3]); > > > > -- > 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