diff options
Diffstat (limited to 'kernel/panic.c')
| -rw-r--r-- | kernel/panic.c | 84 |
1 files changed, 52 insertions, 32 deletions
diff --git a/kernel/panic.c b/kernel/panic.c index 12c5a0a6c89b..6513aac8e992 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include <linux/kallsyms.h> | 23 | #include <linux/kallsyms.h> |
| 24 | 24 | ||
| 25 | int panic_on_oops; | 25 | int panic_on_oops; |
| 26 | int tainted; | 26 | static unsigned long tainted_mask; |
| 27 | static int pause_on_oops; | 27 | static int pause_on_oops; |
| 28 | static int pause_on_oops_flag; | 28 | static int pause_on_oops_flag; |
| 29 | static DEFINE_SPINLOCK(pause_on_oops_lock); | 29 | static DEFINE_SPINLOCK(pause_on_oops_lock); |
| @@ -34,13 +34,6 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list); | |||
| 34 | 34 | ||
| 35 | EXPORT_SYMBOL(panic_notifier_list); | 35 | EXPORT_SYMBOL(panic_notifier_list); |
| 36 | 36 | ||
| 37 | static 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 | |||
| 44 | static long no_blink(long time) | 37 | static long no_blink(long time) |
| 45 | { | 38 | { |
| 46 | return 0; | 39 | return 0; |
| @@ -143,6 +136,27 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
| 143 | 136 | ||
| 144 | EXPORT_SYMBOL(panic); | 137 | EXPORT_SYMBOL(panic); |
| 145 | 138 | ||
| 139 | |||
| 140 | struct tnt { | ||
| 141 | u8 bit; | ||
| 142 | char true; | ||
| 143 | char false; | ||
| 144 | }; | ||
| 145 | |||
| 146 | static const struct tnt tnts[] = { | ||
| 147 | { TAINT_PROPRIETARY_MODULE, 'P', 'G' }, | ||
| 148 | { TAINT_FORCED_MODULE, 'F', ' ' }, | ||
| 149 | { TAINT_UNSAFE_SMP, 'S', ' ' }, | ||
| 150 | { TAINT_FORCED_RMMOD, 'R', ' ' }, | ||
| 151 | { TAINT_MACHINE_CHECK, 'M', ' ' }, | ||
| 152 | { TAINT_BAD_PAGE, 'B', ' ' }, | ||
| 153 | { TAINT_USER, 'U', ' ' }, | ||
| 154 | { TAINT_DIE, 'D', ' ' }, | ||
| 155 | { TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' }, | ||
| 156 | { TAINT_WARN, 'W', ' ' }, | ||
| 157 | { TAINT_CRAP, 'C', ' ' }, | ||
| 158 | }; | ||
| 159 | |||
| 146 | /** | 160 | /** |
| 147 | * print_tainted - return a string to represent the kernel taint state. | 161 | * print_tainted - return a string to represent the kernel taint state. |
| 148 | * | 162 | * |
| @@ -155,44 +169,47 @@ EXPORT_SYMBOL(panic); | |||
| 155 | * 'U' - Userspace-defined naughtiness. | 169 | * 'U' - Userspace-defined naughtiness. |
| 156 | * 'A' - ACPI table overridden. | 170 | * 'A' - ACPI table overridden. |
| 157 | * 'W' - Taint on warning. | 171 | * 'W' - Taint on warning. |
| 172 | * 'C' - modules from drivers/staging are loaded. | ||
| 158 | * | 173 | * |
| 159 | * The string is overwritten by the next call to print_taint(). | 174 | * The string is overwritten by the next call to print_taint(). |
| 160 | */ | 175 | */ |
| 161 | |||
| 162 | const char *print_tainted(void) | 176 | const char *print_tainted(void) |
| 163 | { | 177 | { |
| 164 | static char buf[20]; | 178 | static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ") + 1]; |
| 165 | if (tainted) { | 179 | |
| 166 | snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c%c", | 180 | if (tainted_mask) { |
| 167 | tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', | 181 | char *s; |
| 168 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', | 182 | int i; |
| 169 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', | 183 | |
| 170 | tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', | 184 | s = buf + sprintf(buf, "Tainted: "); |
| 171 | tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', | 185 | for (i = 0; i < ARRAY_SIZE(tnts); i++) { |
| 172 | tainted & TAINT_BAD_PAGE ? 'B' : ' ', | 186 | const struct tnt *t = &tnts[i]; |
| 173 | tainted & TAINT_USER ? 'U' : ' ', | 187 | *s++ = test_bit(t->bit, &tainted_mask) ? |
| 174 | tainted & TAINT_DIE ? 'D' : ' ', | 188 | t->true : t->false; |
| 175 | tainted & TAINT_OVERRIDDEN_ACPI_TABLE ? 'A' : ' ', | 189 | } |
| 176 | tainted & TAINT_WARN ? 'W' : ' '); | 190 | *s = 0; |
| 177 | } | 191 | } else |
| 178 | else | ||
| 179 | snprintf(buf, sizeof(buf), "Not tainted"); | 192 | snprintf(buf, sizeof(buf), "Not tainted"); |
| 180 | return(buf); | 193 | return(buf); |
| 181 | } | 194 | } |
| 182 | 195 | ||
| 183 | void add_taint(unsigned flag) | 196 | int test_taint(unsigned flag) |
| 184 | { | 197 | { |
| 185 | debug_locks = 0; /* can't trust the integrity of the kernel anymore */ | 198 | return test_bit(flag, &tainted_mask); |
| 186 | tainted |= flag; | 199 | } |
| 200 | EXPORT_SYMBOL(test_taint); | ||
| 201 | |||
| 202 | unsigned long get_taint(void) | ||
| 203 | { | ||
| 204 | return tainted_mask; | ||
| 187 | } | 205 | } |
| 188 | EXPORT_SYMBOL(add_taint); | ||
| 189 | 206 | ||
| 190 | static int __init pause_on_oops_setup(char *str) | 207 | void add_taint(unsigned flag) |
| 191 | { | 208 | { |
| 192 | pause_on_oops = simple_strtoul(str, NULL, 0); | 209 | debug_locks = 0; /* can't trust the integrity of the kernel anymore */ |
| 193 | return 1; | 210 | set_bit(flag, &tainted_mask); |
| 194 | } | 211 | } |
| 195 | __setup("pause_on_oops=", pause_on_oops_setup); | 212 | EXPORT_SYMBOL(add_taint); |
| 196 | 213 | ||
| 197 | static void spin_msec(int msecs) | 214 | static void spin_msec(int msecs) |
| 198 | { | 215 | { |
| @@ -353,3 +370,6 @@ void __stack_chk_fail(void) | |||
| 353 | } | 370 | } |
| 354 | EXPORT_SYMBOL(__stack_chk_fail); | 371 | EXPORT_SYMBOL(__stack_chk_fail); |
| 355 | #endif | 372 | #endif |
| 373 | |||
| 374 | core_param(panic, panic_timeout, int, 0644); | ||
| 375 | core_param(pause_on_oops, pause_on_oops, int, 0644); | ||
