aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/panic.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
commita9de18eb761f7c1c860964b2e5addc1a35c7e861 (patch)
tree886e75fdfd09690cd262ca69cb7f5d1d42b48602 /kernel/panic.c
parentb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (diff)
parent6a94cb73064c952255336cc57731904174b2c58f (diff)
Merge branch 'linus' into stackprotector
Conflicts: arch/x86/include/asm/pda.h kernel/fork.c
Diffstat (limited to 'kernel/panic.c')
-rw-r--r--kernel/panic.c117
1 files changed, 65 insertions, 52 deletions
diff --git a/kernel/panic.c b/kernel/panic.c
index e0a87bb025c0..3a0b0898690a 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -21,9 +21,10 @@
21#include <linux/debug_locks.h> 21#include <linux/debug_locks.h>
22#include <linux/random.h> 22#include <linux/random.h>
23#include <linux/kallsyms.h> 23#include <linux/kallsyms.h>
24#include <linux/dmi.h>
24 25
25int panic_on_oops; 26int panic_on_oops;
26int tainted; 27static unsigned long tainted_mask;
27static int pause_on_oops; 28static int pause_on_oops;
28static int pause_on_oops_flag; 29static int pause_on_oops_flag;
29static DEFINE_SPINLOCK(pause_on_oops_lock); 30static DEFINE_SPINLOCK(pause_on_oops_lock);
@@ -34,13 +35,6 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
34 35
35EXPORT_SYMBOL(panic_notifier_list); 36EXPORT_SYMBOL(panic_notifier_list);
36 37
37static int __init panic_setup(char *str)
38{
39 panic_timeout = simple_strtoul(str, NULL, 0);
40 return 1;
41}
42__setup("panic=", panic_setup);
43
44static long no_blink(long time) 38static long no_blink(long time)
45{ 39{
46 return 0; 40 return 0;
@@ -146,6 +140,27 @@ NORET_TYPE void panic(const char * fmt, ...)
146 140
147EXPORT_SYMBOL(panic); 141EXPORT_SYMBOL(panic);
148 142
143
144struct tnt {
145 u8 bit;
146 char true;
147 char false;
148};
149
150static const struct tnt tnts[] = {
151 { TAINT_PROPRIETARY_MODULE, 'P', 'G' },
152 { TAINT_FORCED_MODULE, 'F', ' ' },
153 { TAINT_UNSAFE_SMP, 'S', ' ' },
154 { TAINT_FORCED_RMMOD, 'R', ' ' },
155 { TAINT_MACHINE_CHECK, 'M', ' ' },
156 { TAINT_BAD_PAGE, 'B', ' ' },
157 { TAINT_USER, 'U', ' ' },
158 { TAINT_DIE, 'D', ' ' },
159 { TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' },
160 { TAINT_WARN, 'W', ' ' },
161 { TAINT_CRAP, 'C', ' ' },
162};
163
149/** 164/**
150 * print_tainted - return a string to represent the kernel taint state. 165 * print_tainted - return a string to represent the kernel taint state.
151 * 166 *
@@ -156,46 +171,50 @@ EXPORT_SYMBOL(panic);
156 * 'M' - System experienced a machine check exception. 171 * 'M' - System experienced a machine check exception.
157 * 'B' - System has hit bad_page. 172 * 'B' - System has hit bad_page.
158 * 'U' - Userspace-defined naughtiness. 173 * 'U' - Userspace-defined naughtiness.
174 * 'D' - Kernel has oopsed before
159 * 'A' - ACPI table overridden. 175 * 'A' - ACPI table overridden.
160 * 'W' - Taint on warning. 176 * 'W' - Taint on warning.
177 * 'C' - modules from drivers/staging are loaded.
161 * 178 *
162 * The string is overwritten by the next call to print_taint(). 179 * The string is overwritten by the next call to print_taint().
163 */ 180 */
164
165const char *print_tainted(void) 181const char *print_tainted(void)
166{ 182{
167 static char buf[20]; 183 static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ") + 1];
168 if (tainted) { 184
169 snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c%c", 185 if (tainted_mask) {
170 tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', 186 char *s;
171 tainted & TAINT_FORCED_MODULE ? 'F' : ' ', 187 int i;
172 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', 188
173 tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', 189 s = buf + sprintf(buf, "Tainted: ");
174 tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', 190 for (i = 0; i < ARRAY_SIZE(tnts); i++) {
175 tainted & TAINT_BAD_PAGE ? 'B' : ' ', 191 const struct tnt *t = &tnts[i];
176 tainted & TAINT_USER ? 'U' : ' ', 192 *s++ = test_bit(t->bit, &tainted_mask) ?
177 tainted & TAINT_DIE ? 'D' : ' ', 193 t->true : t->false;
178 tainted & TAINT_OVERRIDDEN_ACPI_TABLE ? 'A' : ' ', 194 }
179 tainted & TAINT_WARN ? 'W' : ' '); 195 *s = 0;
180 } 196 } else
181 else
182 snprintf(buf, sizeof(buf), "Not tainted"); 197 snprintf(buf, sizeof(buf), "Not tainted");
183 return(buf); 198 return(buf);
184} 199}
185 200
186void add_taint(unsigned flag) 201int test_taint(unsigned flag)
187{ 202{
188 debug_locks = 0; /* can't trust the integrity of the kernel anymore */ 203 return test_bit(flag, &tainted_mask);
189 tainted |= flag; 204}
205EXPORT_SYMBOL(test_taint);
206
207unsigned long get_taint(void)
208{
209 return tainted_mask;
190} 210}
191EXPORT_SYMBOL(add_taint);
192 211
193static int __init pause_on_oops_setup(char *str) 212void add_taint(unsigned flag)
194{ 213{
195 pause_on_oops = simple_strtoul(str, NULL, 0); 214 debug_locks = 0; /* can't trust the integrity of the kernel anymore */
196 return 1; 215 set_bit(flag, &tainted_mask);
197} 216}
198__setup("pause_on_oops=", pause_on_oops_setup); 217EXPORT_SYMBOL(add_taint);
199 218
200static void spin_msec(int msecs) 219static void spin_msec(int msecs)
201{ 220{
@@ -306,36 +325,27 @@ void oops_exit(void)
306} 325}
307 326
308#ifdef WANT_WARN_ON_SLOWPATH 327#ifdef WANT_WARN_ON_SLOWPATH
309void warn_on_slowpath(const char *file, int line)
310{
311 char function[KSYM_SYMBOL_LEN];
312 unsigned long caller = (unsigned long) __builtin_return_address(0);
313 sprint_symbol(function, caller);
314
315 printk(KERN_WARNING "------------[ cut here ]------------\n");
316 printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
317 line, function);
318 print_modules();
319 dump_stack();
320 print_oops_end_marker();
321 add_taint(TAINT_WARN);
322}
323EXPORT_SYMBOL(warn_on_slowpath);
324
325
326void warn_slowpath(const char *file, int line, const char *fmt, ...) 328void warn_slowpath(const char *file, int line, const char *fmt, ...)
327{ 329{
328 va_list args; 330 va_list args;
329 char function[KSYM_SYMBOL_LEN]; 331 char function[KSYM_SYMBOL_LEN];
330 unsigned long caller = (unsigned long)__builtin_return_address(0); 332 unsigned long caller = (unsigned long)__builtin_return_address(0);
333 const char *board;
334
331 sprint_symbol(function, caller); 335 sprint_symbol(function, caller);
332 336
333 printk(KERN_WARNING "------------[ cut here ]------------\n"); 337 printk(KERN_WARNING "------------[ cut here ]------------\n");
334 printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, 338 printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
335 line, function); 339 line, function);
336 va_start(args, fmt); 340 board = dmi_get_system_info(DMI_PRODUCT_NAME);
337 vprintk(fmt, args); 341 if (board)
338 va_end(args); 342 printk(KERN_WARNING "Hardware name: %s\n", board);
343
344 if (fmt) {
345 va_start(args, fmt);
346 vprintk(fmt, args);
347 va_end(args);
348 }
339 349
340 print_modules(); 350 print_modules();
341 dump_stack(); 351 dump_stack();
@@ -363,3 +373,6 @@ void __stack_chk_fail(void)
363EXPORT_SYMBOL(__stack_chk_fail); 373EXPORT_SYMBOL(__stack_chk_fail);
364 374
365#endif 375#endif
376
377core_param(panic, panic_timeout, int, 0644);
378core_param(pause_on_oops, pause_on_oops, int, 0644);