aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2008-04-17 01:46:30 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2008-04-17 01:47:07 -0400
commit9e74a6b8983c2653dd2a6f51e634efa281e95d59 (patch)
tree46a6e3c866a3b7642c6176a9c0ef636267196c0f /arch/s390
parent1a5debaaace41f1e91014332e6eedde4499e5638 (diff)
[S390] kernel: show last breaking-event-address on oops
Newer s390 models have a breaking-event-address-recording register. Each time an instruction causes a break in the sequential instruction execution, the address is saved in that hardware register. On a program interrupt the address is copied to the lowcore address 272-279, which makes it software accessible. This patch changes the program check handler and the stack overflow checker to copy the value into the pt_regs argument. The oops output is enhanced to show the last known breaking address. It might give additional information if the stack trace is corrupted. The feature is only available on 64 bit. The new oops output looks like: [---------snip----------] Modules linked in: vmcp sunrpc qeth_l2 dm_mod qeth ccwgroup CPU: 2 Not tainted 2.6.24zlive-host #8 Process modprobe (pid: 4788, task: 00000000bf3d8718, ksp: 00000000b2b0b8e0) Krnl PSW : 0704200180000000 000003e000020028 (vmcp_init+0x28/0xe4 [vmcp]) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:0 CC:2 PM:0 EA:3 Krnl GPRS: 0000000004000002 000003e000020000 0000000000000000 0000000000000001 000000000015734c ffffffffffffffff 000003e0000b3b00 0000000000000000 000003e00007ca30 00000000b5bb5d40 00000000b5bb5800 000003e0000b3b00 000003e0000a2000 00000000003ecf50 00000000b2b0bd50 00000000b2b0bcb0 Krnl Code: 000003e000020018: c0c000040ff4 larl %r12,3e0000a2000 000003e00002001e: e3e0f0000024 stg %r14,0(%r15) 000003e000020024: a7f40001 brc 15,3e000020026 >000003e000020028: e310c0100004 lg %r1,16(%r12) 000003e00002002e: c020000413dc larl %r2,3e0000a27e6 000003e000020034: c0a00004aee6 larl %r10,3e0000b5e00 000003e00002003a: a7490001 lghi %r4,1 000003e00002003e: a75900f0 lghi %r5,240 Call Trace: ([<000000000014b300>] blocking_notifier_call_chain+0x2c/0x40) [<000000000015735c>] sys_init_module+0x19d8/0x1b08 [<0000000000110afc>] sysc_noemu+0x10/0x16 [<000002000011cda2>] 0x2000011cda2 Last Breaking-Event-Address: [<000003e000020024>] vmcp_init+0x24/0xe4 [vmcp] [---------snip----------] Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kernel/entry64.S2
-rw-r--r--arch/s390/kernel/process.c1
-rw-r--r--arch/s390/kernel/traps.c10
3 files changed, 12 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 */