diff options
Diffstat (limited to 'arch/s390/kernel/dumpstack.c')
| -rw-r--r-- | arch/s390/kernel/dumpstack.c | 63 | 
1 files changed, 22 insertions, 41 deletions
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 6693383bc01b..55d4fe174fd9 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -38,10 +38,10 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,  		if (sp < low || sp > high - sizeof(*sf))  			return sp;  		sf = (struct stack_frame *) sp; +		if (func(data, sf->gprs[8], 0)) +			return sp;  		/* Follow the backchain. */  		while (1) { -			if (func(data, sf->gprs[8])) -				return sp;  			low = sp;  			sp = sf->back_chain;  			if (!sp) @@ -49,6 +49,8 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,  			if (sp <= low || sp > high - sizeof(*sf))  				return sp;  			sf = (struct stack_frame *) sp; +			if (func(data, sf->gprs[8], 1)) +				return sp;  		}  		/* Zero backchain detected, check for interrupt frame. */  		sp = (unsigned long) (sf + 1); @@ -56,7 +58,7 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,  			return sp;  		regs = (struct pt_regs *) sp;  		if (!user_mode(regs)) { -			if (func(data, regs->psw.addr)) +			if (func(data, regs->psw.addr, 1))  				return sp;  		}  		low = sp; @@ -85,33 +87,12 @@ void dump_trace(dump_trace_func_t func, void *data, struct task_struct *task,  }  EXPORT_SYMBOL_GPL(dump_trace); -struct return_address_data { -	unsigned long address; -	int depth; -}; - -static int __return_address(void *data, unsigned long address) -{ -	struct return_address_data *rd = data; - -	if (rd->depth--) -		return 0; -	rd->address = address; -	return 1; -} - -unsigned long return_address(int depth) -{ -	struct return_address_data rd = { .depth = depth + 2 }; - -	dump_trace(__return_address, &rd, NULL, current_stack_pointer()); -	return rd.address; -} -EXPORT_SYMBOL_GPL(return_address); - -static int show_address(void *data, unsigned long address) +static int show_address(void *data, unsigned long address, int reliable)  { -	printk("([<%016lx>] %pSR)\n", address, (void *)address); +	if (reliable) +		printk(" [<%016lx>] %pSR \n", address, (void *)address); +	else +		printk("([<%016lx>] %pSR)\n", address, (void *)address);  	return 0;  } @@ -138,14 +119,14 @@ void show_stack(struct task_struct *task, unsigned long *sp)  		else  			stack = (unsigned long *)task->thread.ksp;  	} +	printk(KERN_DEFAULT "Stack:\n");  	for (i = 0; i < 20; i++) {  		if (((addr_t) stack & (THREAD_SIZE-1)) == 0)  			break; -		if ((i * sizeof(long) % 32) == 0) -			printk("%s       ", i == 0 ? "" : "\n"); -		printk("%016lx ", *stack++); +		if (i % 4 == 0) +			printk(KERN_DEFAULT "       "); +		pr_cont("%016lx%c", *stack++, i % 4 == 3 ? '\n' : ' ');  	} -	printk("\n");  	show_trace(task, (unsigned long)sp);  } @@ -163,13 +144,13 @@ void show_registers(struct pt_regs *regs)  	mode = user_mode(regs) ? "User" : "Krnl";  	printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);  	if (!user_mode(regs)) -		printk(" (%pSR)", (void *)regs->psw.addr); -	printk("\n"); +		pr_cont(" (%pSR)", (void *)regs->psw.addr); +	pr_cont("\n");  	printk("           R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "  	       "P:%x AS:%x CC:%x PM:%x", psw->r, psw->t, psw->i, psw->e,  	       psw->key, psw->m, psw->w, psw->p, psw->as, psw->cc, psw->pm); -	printk(" RI:%x EA:%x", psw->ri, psw->eaba); -	printk("\n%s GPRS: %016lx %016lx %016lx %016lx\n", mode, +	pr_cont(" RI:%x EA:%x\n", psw->ri, psw->eaba); +	printk("%s GPRS: %016lx %016lx %016lx %016lx\n", mode,  	       regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]);  	printk("           %016lx %016lx %016lx %016lx\n",  	       regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); @@ -205,14 +186,14 @@ void die(struct pt_regs *regs, const char *str)  	printk("%s: %04x ilc:%d [#%d] ", str, regs->int_code & 0xffff,  	       regs->int_code >> 17, ++die_counter);  #ifdef CONFIG_PREEMPT -	printk("PREEMPT "); +	pr_cont("PREEMPT ");  #endif  #ifdef CONFIG_SMP -	printk("SMP "); +	pr_cont("SMP ");  #endif  	if (debug_pagealloc_enabled()) -		printk("DEBUG_PAGEALLOC"); -	printk("\n"); +		pr_cont("DEBUG_PAGEALLOC"); +	pr_cont("\n");  	notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV);  	print_modules();  	show_regs(regs);  | 
