[Crash-utility] [PATCH] s390: Fix backtrace code
Dave Anderson
anderson at redhat.com
Fri Feb 26 14:50:12 UTC 2010
----- "Michael Holzheu" <holzheu at linux.vnet.ibm.com> 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 at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
More information about the Crash-utility
mailing list