diff options
Diffstat (limited to 'kernel/panic.c')
| -rw-r--r-- | kernel/panic.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/kernel/panic.c b/kernel/panic.c index 081f7465fc8d..74ba5f3e46c7 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/sysrq.h> | 18 | #include <linux/sysrq.h> |
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/nmi.h> | 20 | #include <linux/nmi.h> |
| 21 | #include <linux/kexec.h> | ||
| 21 | 22 | ||
| 22 | int panic_timeout; | 23 | int panic_timeout; |
| 23 | int panic_on_oops; | 24 | int panic_on_oops; |
| @@ -63,6 +64,13 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
| 63 | unsigned long caller = (unsigned long) __builtin_return_address(0); | 64 | unsigned long caller = (unsigned long) __builtin_return_address(0); |
| 64 | #endif | 65 | #endif |
| 65 | 66 | ||
| 67 | /* | ||
| 68 | * It's possible to come here directly from a panic-assertion and not | ||
| 69 | * have preempt disabled. Some functions called from here want | ||
| 70 | * preempt to be disabled. No point enabling it later though... | ||
| 71 | */ | ||
| 72 | preempt_disable(); | ||
| 73 | |||
| 66 | bust_spinlocks(1); | 74 | bust_spinlocks(1); |
| 67 | va_start(args, fmt); | 75 | va_start(args, fmt); |
| 68 | vsnprintf(buf, sizeof(buf), fmt, args); | 76 | vsnprintf(buf, sizeof(buf), fmt, args); |
| @@ -70,7 +78,19 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
| 70 | printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); | 78 | printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); |
| 71 | bust_spinlocks(0); | 79 | bust_spinlocks(0); |
| 72 | 80 | ||
| 81 | /* | ||
| 82 | * If we have crashed and we have a crash kernel loaded let it handle | ||
| 83 | * everything else. | ||
| 84 | * Do we want to call this before we try to display a message? | ||
| 85 | */ | ||
| 86 | crash_kexec(NULL); | ||
| 87 | |||
| 73 | #ifdef CONFIG_SMP | 88 | #ifdef CONFIG_SMP |
| 89 | /* | ||
| 90 | * Note smp_send_stop is the usual smp shutdown function, which | ||
| 91 | * unfortunately means it may not be hardened to work in a panic | ||
| 92 | * situation. | ||
| 93 | */ | ||
| 74 | smp_send_stop(); | 94 | smp_send_stop(); |
| 75 | #endif | 95 | #endif |
| 76 | 96 | ||
| @@ -79,8 +99,7 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
| 79 | if (!panic_blink) | 99 | if (!panic_blink) |
| 80 | panic_blink = no_blink; | 100 | panic_blink = no_blink; |
| 81 | 101 | ||
| 82 | if (panic_timeout > 0) | 102 | if (panic_timeout > 0) { |
| 83 | { | ||
| 84 | /* | 103 | /* |
| 85 | * Delay timeout seconds before rebooting the machine. | 104 | * Delay timeout seconds before rebooting the machine. |
| 86 | * We can't use the "normal" timers since we just panicked.. | 105 | * We can't use the "normal" timers since we just panicked.. |
