traps.c (9b00ac06978c54788f13eefd34a07b77db48d567) | traps.c (760ca4dc90e624eb8f7ff85a5925151e25577758) |
---|---|
1/* 2 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright 2007-2010 Freescale Semiconductor, Inc. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. --- 84 unchanged lines hidden (view full) --- 93 backlight_update_status(pmac_backlight); 94 } 95 mutex_unlock(&pmac_backlight_mutex); 96} 97#else 98static inline void pmac_backlight_unblank(void) { } 99#endif 100 | 1/* 2 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright 2007-2010 Freescale Semiconductor, Inc. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. --- 84 unchanged lines hidden (view full) --- 93 backlight_update_status(pmac_backlight); 94 } 95 mutex_unlock(&pmac_backlight_mutex); 96} 97#else 98static inline void pmac_backlight_unblank(void) { } 99#endif 100 |
101int die(const char *str, struct pt_regs *regs, long err) | 101static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; 102static int die_owner = -1; 103static unsigned int die_nest_count; 104static int die_counter; 105 106static unsigned __kprobes long oops_begin(struct pt_regs *regs) |
102{ | 107{ |
103 static struct { 104 raw_spinlock_t lock; 105 u32 lock_owner; 106 int lock_owner_depth; 107 } die = { 108 .lock = __RAW_SPIN_LOCK_UNLOCKED(die.lock), 109 .lock_owner = -1, 110 .lock_owner_depth = 0 111 }; 112 static int die_counter; | 108 int cpu; |
113 unsigned long flags; 114 115 if (debugger(regs)) 116 return 1; 117 118 oops_enter(); 119 | 109 unsigned long flags; 110 111 if (debugger(regs)) 112 return 1; 113 114 oops_enter(); 115 |
120 if (die.lock_owner != raw_smp_processor_id()) { 121 console_verbose(); 122 raw_spin_lock_irqsave(&die.lock, flags); 123 die.lock_owner = smp_processor_id(); 124 die.lock_owner_depth = 0; 125 bust_spinlocks(1); 126 if (machine_is(powermac)) 127 pmac_backlight_unblank(); 128 } else { 129 local_save_flags(flags); | 116 /* racy, but better than risking deadlock. */ 117 raw_local_irq_save(flags); 118 cpu = smp_processor_id(); 119 if (!arch_spin_trylock(&die_lock)) { 120 if (cpu == die_owner) 121 /* nested oops. should stop eventually */; 122 else 123 arch_spin_lock(&die_lock); |
130 } | 124 } |
125 die_nest_count++; 126 die_owner = cpu; 127 console_verbose(); 128 bust_spinlocks(1); 129 if (machine_is(powermac)) 130 pmac_backlight_unblank(); 131 return flags; 132} |
|
131 | 133 |
132 if (++die.lock_owner_depth < 3) { 133 printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); 134#ifdef CONFIG_PREEMPT 135 printk("PREEMPT "); 136#endif 137#ifdef CONFIG_SMP 138 printk("SMP NR_CPUS=%d ", NR_CPUS); 139#endif 140#ifdef CONFIG_DEBUG_PAGEALLOC 141 printk("DEBUG_PAGEALLOC "); 142#endif 143#ifdef CONFIG_NUMA 144 printk("NUMA "); 145#endif 146 printk("%s\n", ppc_md.name ? ppc_md.name : ""); 147 148 if (notify_die(DIE_OOPS, str, regs, err, 255, 149 SIGSEGV) == NOTIFY_STOP) 150 return 1; 151 152 print_modules(); 153 show_regs(regs); 154 } else { 155 printk("Recursive die() failure, output suppressed\n"); 156 } 157 | 134static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, 135 int signr) 136{ |
158 bust_spinlocks(0); | 137 bust_spinlocks(0); |
159 die.lock_owner = -1; | 138 die_owner = -1; |
160 add_taint(TAINT_DIE); | 139 add_taint(TAINT_DIE); |
140 die_nest_count--; |
|
161 oops_exit(); 162 printk("\n"); | 141 oops_exit(); 142 printk("\n"); |
163 raw_spin_unlock_irqrestore(&die.lock, flags); | 143 if (!die_nest_count) 144 /* Nest count reaches zero, release the lock. */ 145 arch_spin_unlock(&die_lock); 146 raw_local_irq_restore(flags); |
164 165 /* 166 * A system reset (0x100) is a request to dump, so we always send 167 * it through the crashdump code. 168 */ 169 if (kexec_should_crash(current) || (TRAP(regs) == 0x100)) { 170 crash_kexec(regs); 171 172 /* 173 * We aren't the primary crash CPU. We need to send it 174 * to a holding pattern to avoid it ending up in the panic 175 * code. 176 */ 177 crash_kexec_secondary(regs); 178 } 179 | 147 148 /* 149 * A system reset (0x100) is a request to dump, so we always send 150 * it through the crashdump code. 151 */ 152 if (kexec_should_crash(current) || (TRAP(regs) == 0x100)) { 153 crash_kexec(regs); 154 155 /* 156 * We aren't the primary crash CPU. We need to send it 157 * to a holding pattern to avoid it ending up in the panic 158 * code. 159 */ 160 crash_kexec_secondary(regs); 161 } 162 |
163 if (!signr) 164 return; 165 |
|
180 /* 181 * While our oops output is serialised by a spinlock, output 182 * from panic() called below can race and corrupt it. If we 183 * know we are going to panic, delay for 1 second so we have a 184 * chance to get clean backtraces from all CPUs that are oopsing. 185 */ 186 if (in_interrupt() || panic_on_oops || !current->pid || 187 is_global_init(current)) { 188 mdelay(MSEC_PER_SEC); 189 } 190 191 if (in_interrupt()) 192 panic("Fatal exception in interrupt"); | 166 /* 167 * While our oops output is serialised by a spinlock, output 168 * from panic() called below can race and corrupt it. If we 169 * know we are going to panic, delay for 1 second so we have a 170 * chance to get clean backtraces from all CPUs that are oopsing. 171 */ 172 if (in_interrupt() || panic_on_oops || !current->pid || 173 is_global_init(current)) { 174 mdelay(MSEC_PER_SEC); 175 } 176 177 if (in_interrupt()) 178 panic("Fatal exception in interrupt"); |
193 | |
194 if (panic_on_oops) 195 panic("Fatal exception"); | 179 if (panic_on_oops) 180 panic("Fatal exception"); |
181 do_exit(signr); 182} |
|
196 | 183 |
197 do_exit(err); | 184static int __kprobes __die(const char *str, struct pt_regs *regs, long err) 185{ 186 printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); 187#ifdef CONFIG_PREEMPT 188 printk("PREEMPT "); 189#endif 190#ifdef CONFIG_SMP 191 printk("SMP NR_CPUS=%d ", NR_CPUS); 192#endif 193#ifdef CONFIG_DEBUG_PAGEALLOC 194 printk("DEBUG_PAGEALLOC "); 195#endif 196#ifdef CONFIG_NUMA 197 printk("NUMA "); 198#endif 199 printk("%s\n", ppc_md.name ? ppc_md.name : ""); |
198 | 200 |
201 if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV) == NOTIFY_STOP) 202 return 1; 203 204 print_modules(); 205 show_regs(regs); 206 |
|
199 return 0; 200} 201 | 207 return 0; 208} 209 |
210void die(const char *str, struct pt_regs *regs, long err) 211{ 212 unsigned long flags = oops_begin(regs); 213 214 if (__die(str, regs, err)) 215 err = 0; 216 oops_end(flags, regs, err); 217} 218 |
|
202void user_single_step_siginfo(struct task_struct *tsk, 203 struct pt_regs *regs, siginfo_t *info) 204{ 205 memset(info, 0, sizeof(*info)); 206 info->si_signo = SIGTRAP; 207 info->si_code = TRAP_TRACE; 208 info->si_addr = (void __user *)regs->nip; 209} 210 211void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) 212{ 213 siginfo_t info; 214 const char fmt32[] = KERN_INFO "%s[%d]: unhandled signal %d " \ 215 "at %08lx nip %08lx lr %08lx code %x\n"; 216 const char fmt64[] = KERN_INFO "%s[%d]: unhandled signal %d " \ 217 "at %016lx nip %016lx lr %016lx code %x\n"; 218 219 if (!user_mode(regs)) { | 219void user_single_step_siginfo(struct task_struct *tsk, 220 struct pt_regs *regs, siginfo_t *info) 221{ 222 memset(info, 0, sizeof(*info)); 223 info->si_signo = SIGTRAP; 224 info->si_code = TRAP_TRACE; 225 info->si_addr = (void __user *)regs->nip; 226} 227 228void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) 229{ 230 siginfo_t info; 231 const char fmt32[] = KERN_INFO "%s[%d]: unhandled signal %d " \ 232 "at %08lx nip %08lx lr %08lx code %x\n"; 233 const char fmt64[] = KERN_INFO "%s[%d]: unhandled signal %d " \ 234 "at %016lx nip %016lx lr %016lx code %x\n"; 235 236 if (!user_mode(regs)) { |
220 if (die("Exception in kernel mode", regs, signr)) 221 return; 222 } else if (show_unhandled_signals && 223 unhandled_signal(current, signr)) { | 237 die("Exception in kernel mode", regs, signr); 238 return; 239 } 240 241 if (show_unhandled_signals && unhandled_signal(current, signr)) { |
224 printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, 225 current->comm, current->pid, signr, 226 addr, regs->nip, regs->link, code); 227 } 228 229 memset(&info, 0, sizeof(info)); 230 info.si_signo = signr; 231 info.si_code = code; --- 1365 unchanged lines hidden --- | 242 printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, 243 current->comm, current->pid, signr, 244 addr, regs->nip, regs->link, code); 245 } 246 247 memset(&info, 0, sizeof(info)); 248 info.si_signo = signr; 249 info.si_code = code; --- 1365 unchanged lines hidden --- |