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..66f43d33cd80 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(); | ||
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.. |