aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/kernel/entry64.S2
-rw-r--r--arch/s390/kernel/process.c1
-rw-r--r--arch/s390/kernel/traps.c10
-rw-r--r--include/asm-s390/lowcore.h2
-rw-r--r--include/asm-s390/processor.h7
5 files changed, 21 insertions, 1 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index efde6e178f6c..cd959c0b2e16 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -475,6 +475,7 @@ pgm_check_handler:
475pgm_no_vtime: 475pgm_no_vtime:
476#endif 476#endif
477 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 477 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
478 mvc SP_ARGS(8,%r15),__LC_LAST_BREAK
478 TRACE_IRQS_OFF 479 TRACE_IRQS_OFF
479 lgf %r3,__LC_PGM_ILC # load program interruption code 480 lgf %r3,__LC_PGM_ILC # load program interruption code
480 lghi %r8,0x7f 481 lghi %r8,0x7f
@@ -847,6 +848,7 @@ stack_overflow:
847 je 0f 848 je 0f
848 la %r1,__LC_SAVE_AREA+32 849 la %r1,__LC_SAVE_AREA+32
8490: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack 8500: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack
851 mvc SP_ARGS(8,%r15),__LC_LAST_BREAK
850 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain 852 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
851 la %r2,SP_PTREGS(%r15) # load pt_regs 853 la %r2,SP_PTREGS(%r15) # load pt_regs
852 jg kernel_stack_overflow 854 jg kernel_stack_overflow
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index dbefd0db395f..c1aff194141d 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -195,6 +195,7 @@ void show_regs(struct pt_regs *regs)
195 /* Show stack backtrace if pt_regs is from kernel mode */ 195 /* Show stack backtrace if pt_regs is from kernel mode */
196 if (!(regs->psw.mask & PSW_MASK_PSTATE)) 196 if (!(regs->psw.mask & PSW_MASK_PSTATE))
197 show_trace(NULL, (unsigned long *) regs->gprs[15]); 197 show_trace(NULL, (unsigned long *) regs->gprs[15]);
198 show_last_breaking_event(regs);
198} 199}
199 200
200extern void kernel_thread_starter(void); 201extern void kernel_thread_starter(void);
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index b3524134f213..57b607b61100 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -134,7 +134,6 @@ void show_trace(struct task_struct *task, unsigned long *stack)
134 else 134 else
135 __show_trace(sp, S390_lowcore.thread_info, 135 __show_trace(sp, S390_lowcore.thread_info,
136 S390_lowcore.thread_info + THREAD_SIZE); 136 S390_lowcore.thread_info + THREAD_SIZE);
137 printk("\n");
138 if (!task) 137 if (!task)
139 task = current; 138 task = current;
140 debug_show_held_locks(task); 139 debug_show_held_locks(task);
@@ -162,6 +161,15 @@ void show_stack(struct task_struct *task, unsigned long *sp)
162 show_trace(task, sp); 161 show_trace(task, sp);
163} 162}
164 163
164#ifdef CONFIG_64BIT
165void show_last_breaking_event(struct pt_regs *regs)
166{
167 printk("Last Breaking-Event-Address:\n");
168 printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN);
169 print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN);
170}
171#endif
172
165/* 173/*
166 * The architecture-independent dump_stack generator 174 * The architecture-independent dump_stack generator
167 */ 175 */
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index 007c8a4941b2..5de3efb31445 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -56,6 +56,8 @@
56#define __LC_IO_INT_WORD 0x0C0 56#define __LC_IO_INT_WORD 0x0C0
57#define __LC_MCCK_CODE 0x0E8 57#define __LC_MCCK_CODE 0x0E8
58 58
59#define __LC_LAST_BREAK 0x110
60
59#define __LC_RETURN_PSW 0x200 61#define __LC_RETURN_PSW 0x200
60 62
61#define __LC_SAVE_AREA 0xC00 63#define __LC_SAVE_AREA 0xC00
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index 51d88912aa20..8eaf343a12a8 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -175,6 +175,13 @@ extern void task_show_regs(struct seq_file *m, struct task_struct *task);
175extern void show_registers(struct pt_regs *regs); 175extern void show_registers(struct pt_regs *regs);
176extern void show_code(struct pt_regs *regs); 176extern void show_code(struct pt_regs *regs);
177extern void show_trace(struct task_struct *task, unsigned long *sp); 177extern void show_trace(struct task_struct *task, unsigned long *sp);
178#ifdef CONFIG_64BIT
179extern void show_last_breaking_event(struct pt_regs *regs);
180#else
181static inline void show_last_breaking_event(struct pt_regs *regs)
182{
183}
184#endif
178 185
179unsigned long get_wchan(struct task_struct *p); 186unsigned long get_wchan(struct task_struct *p);
180#define task_pt_regs(tsk) ((struct pt_regs *) \ 187#define task_pt_regs(tsk) ((struct pt_regs *) \