diff options
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
| -rw-r--r-- | arch/powerpc/kernel/traps.c | 76 | 
1 files changed, 54 insertions, 22 deletions
| diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 17724fb2067f..f7862224fe85 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
| @@ -90,21 +90,11 @@ EXPORT_SYMBOL(unregister_die_notifier); | |||
| 90 | * Trap & Exception support | 90 | * Trap & Exception support | 
| 91 | */ | 91 | */ | 
| 92 | 92 | ||
| 93 | static DEFINE_SPINLOCK(die_lock); | ||
| 94 | |||
| 95 | int die(const char *str, struct pt_regs *regs, long err) | ||
| 96 | { | ||
| 97 | static int die_counter; | ||
| 98 | |||
| 99 | if (debugger(regs)) | ||
| 100 | return 1; | ||
| 101 | |||
| 102 | console_verbose(); | ||
| 103 | spin_lock_irq(&die_lock); | ||
| 104 | bust_spinlocks(1); | ||
| 105 | #ifdef CONFIG_PMAC_BACKLIGHT | 93 | #ifdef CONFIG_PMAC_BACKLIGHT | 
| 94 | static void pmac_backlight_unblank(void) | ||
| 95 | { | ||
| 106 | mutex_lock(&pmac_backlight_mutex); | 96 | mutex_lock(&pmac_backlight_mutex); | 
| 107 | if (machine_is(powermac) && pmac_backlight) { | 97 | if (pmac_backlight) { | 
| 108 | struct backlight_properties *props; | 98 | struct backlight_properties *props; | 
| 109 | 99 | ||
| 110 | props = &pmac_backlight->props; | 100 | props = &pmac_backlight->props; | 
| @@ -113,26 +103,67 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
| 113 | backlight_update_status(pmac_backlight); | 103 | backlight_update_status(pmac_backlight); | 
| 114 | } | 104 | } | 
| 115 | mutex_unlock(&pmac_backlight_mutex); | 105 | mutex_unlock(&pmac_backlight_mutex); | 
| 106 | } | ||
| 107 | #else | ||
| 108 | static inline void pmac_backlight_unblank(void) { } | ||
| 116 | #endif | 109 | #endif | 
| 117 | printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); | 110 | |
| 111 | int die(const char *str, struct pt_regs *regs, long err) | ||
| 112 | { | ||
| 113 | static struct { | ||
| 114 | spinlock_t lock; | ||
| 115 | u32 lock_owner; | ||
| 116 | int lock_owner_depth; | ||
| 117 | } die = { | ||
| 118 | .lock = __SPIN_LOCK_UNLOCKED(die.lock), | ||
| 119 | .lock_owner = -1, | ||
| 120 | .lock_owner_depth = 0 | ||
| 121 | }; | ||
| 122 | static int die_counter; | ||
| 123 | unsigned long flags; | ||
| 124 | |||
| 125 | if (debugger(regs)) | ||
| 126 | return 1; | ||
| 127 | |||
| 128 | oops_enter(); | ||
| 129 | |||
| 130 | if (die.lock_owner != raw_smp_processor_id()) { | ||
| 131 | console_verbose(); | ||
| 132 | spin_lock_irqsave(&die.lock, flags); | ||
| 133 | die.lock_owner = smp_processor_id(); | ||
| 134 | die.lock_owner_depth = 0; | ||
| 135 | bust_spinlocks(1); | ||
| 136 | if (machine_is(powermac)) | ||
| 137 | pmac_backlight_unblank(); | ||
| 138 | } else { | ||
| 139 | local_save_flags(flags); | ||
| 140 | } | ||
| 141 | |||
| 142 | if (++die.lock_owner_depth < 3) { | ||
| 143 | printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); | ||
| 118 | #ifdef CONFIG_PREEMPT | 144 | #ifdef CONFIG_PREEMPT | 
| 119 | printk("PREEMPT "); | 145 | printk("PREEMPT "); | 
| 120 | #endif | 146 | #endif | 
| 121 | #ifdef CONFIG_SMP | 147 | #ifdef CONFIG_SMP | 
| 122 | printk("SMP NR_CPUS=%d ", NR_CPUS); | 148 | printk("SMP NR_CPUS=%d ", NR_CPUS); | 
| 123 | #endif | 149 | #endif | 
| 124 | #ifdef CONFIG_DEBUG_PAGEALLOC | 150 | #ifdef CONFIG_DEBUG_PAGEALLOC | 
| 125 | printk("DEBUG_PAGEALLOC "); | 151 | printk("DEBUG_PAGEALLOC "); | 
| 126 | #endif | 152 | #endif | 
| 127 | #ifdef CONFIG_NUMA | 153 | #ifdef CONFIG_NUMA | 
| 128 | printk("NUMA "); | 154 | printk("NUMA "); | 
| 129 | #endif | 155 | #endif | 
| 130 | printk("%s\n", ppc_md.name ? "" : ppc_md.name); | 156 | printk("%s\n", ppc_md.name ? ppc_md.name : ""); | 
| 157 | |||
| 158 | print_modules(); | ||
| 159 | show_regs(regs); | ||
| 160 | } else { | ||
| 161 | printk("Recursive die() failure, output suppressed\n"); | ||
| 162 | } | ||
| 131 | 163 | ||
| 132 | print_modules(); | ||
| 133 | show_regs(regs); | ||
| 134 | bust_spinlocks(0); | 164 | bust_spinlocks(0); | 
| 135 | spin_unlock_irq(&die_lock); | 165 | die.lock_owner = -1; | 
| 166 | spin_unlock_irqrestore(&die.lock, flags); | ||
| 136 | 167 | ||
| 137 | if (kexec_should_crash(current) || | 168 | if (kexec_should_crash(current) || | 
| 138 | kexec_sr_activated(smp_processor_id())) | 169 | kexec_sr_activated(smp_processor_id())) | 
| @@ -145,6 +176,7 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
| 145 | if (panic_on_oops) | 176 | if (panic_on_oops) | 
| 146 | panic("Fatal exception"); | 177 | panic("Fatal exception"); | 
| 147 | 178 | ||
| 179 | oops_exit(); | ||
| 148 | do_exit(err); | 180 | do_exit(err); | 
| 149 | 181 | ||
| 150 | return 0; | 182 | return 0; | 
