diff options
Diffstat (limited to 'kernel/panic.c')
-rw-r--r-- | kernel/panic.c | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/kernel/panic.c b/kernel/panic.c index 98e2047f4db7..bda561ef3cdf 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); |
@@ -143,6 +143,27 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
143 | 143 | ||
144 | EXPORT_SYMBOL(panic); | 144 | EXPORT_SYMBOL(panic); |
145 | 145 | ||
146 | |||
147 | struct tnt { | ||
148 | u8 bit; | ||
149 | char true; | ||
150 | char false; | ||
151 | }; | ||
152 | |||
153 | static const struct tnt tnts[] = { | ||
154 | { TAINT_PROPRIETARY_MODULE, 'P', 'G' }, | ||
155 | { TAINT_FORCED_MODULE, 'F', ' ' }, | ||
156 | { TAINT_UNSAFE_SMP, 'S', ' ' }, | ||
157 | { TAINT_FORCED_RMMOD, 'R', ' ' }, | ||
158 | { TAINT_MACHINE_CHECK, 'M', ' ' }, | ||
159 | { TAINT_BAD_PAGE, 'B', ' ' }, | ||
160 | { TAINT_USER, 'U', ' ' }, | ||
161 | { TAINT_DIE, 'D', ' ' }, | ||
162 | { TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' }, | ||
163 | { TAINT_WARN, 'W', ' ' }, | ||
164 | { TAINT_CRAP, 'C', ' ' }, | ||
165 | }; | ||
166 | |||
146 | /** | 167 | /** |
147 | * print_tainted - return a string to represent the kernel taint state. | 168 | * print_tainted - return a string to represent the kernel taint state. |
148 | * | 169 | * |
@@ -159,33 +180,41 @@ EXPORT_SYMBOL(panic); | |||
159 | * | 180 | * |
160 | * The string is overwritten by the next call to print_taint(). | 181 | * The string is overwritten by the next call to print_taint(). |
161 | */ | 182 | */ |
162 | |||
163 | const char *print_tainted(void) | 183 | const char *print_tainted(void) |
164 | { | 184 | { |
165 | static char buf[20]; | 185 | static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ") + 1]; |
166 | if (tainted) { | 186 | |
167 | snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c%c%c", | 187 | if (tainted_mask) { |
168 | tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', | 188 | char *s; |
169 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', | 189 | int i; |
170 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', | 190 | |
171 | tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', | 191 | s = buf + sprintf(buf, "Tainted: "); |
172 | tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', | 192 | for (i = 0; i < ARRAY_SIZE(tnts); i++) { |
173 | tainted & TAINT_BAD_PAGE ? 'B' : ' ', | 193 | const struct tnt *t = &tnts[i]; |
174 | tainted & TAINT_USER ? 'U' : ' ', | 194 | *s++ = test_bit(t->bit, &tainted_mask) ? |
175 | tainted & TAINT_DIE ? 'D' : ' ', | 195 | t->true : t->false; |
176 | tainted & TAINT_OVERRIDDEN_ACPI_TABLE ? 'A' : ' ', | 196 | } |
177 | tainted & TAINT_WARN ? 'W' : ' ', | 197 | *s = 0; |
178 | tainted & TAINT_CRAP ? 'C' : ' '); | 198 | } else |
179 | } | ||
180 | else | ||
181 | snprintf(buf, sizeof(buf), "Not tainted"); | 199 | snprintf(buf, sizeof(buf), "Not tainted"); |
182 | return(buf); | 200 | return(buf); |
183 | } | 201 | } |
184 | 202 | ||
203 | int test_taint(unsigned flag) | ||
204 | { | ||
205 | return test_bit(flag, &tainted_mask); | ||
206 | } | ||
207 | EXPORT_SYMBOL(test_taint); | ||
208 | |||
209 | unsigned long get_taint(void) | ||
210 | { | ||
211 | return tainted_mask; | ||
212 | } | ||
213 | |||
185 | void add_taint(unsigned flag) | 214 | void add_taint(unsigned flag) |
186 | { | 215 | { |
187 | debug_locks = 0; /* can't trust the integrity of the kernel anymore */ | 216 | debug_locks = 0; /* can't trust the integrity of the kernel anymore */ |
188 | tainted |= flag; | 217 | set_bit(flag, &tainted_mask); |
189 | } | 218 | } |
190 | EXPORT_SYMBOL(add_taint); | 219 | EXPORT_SYMBOL(add_taint); |
191 | 220 | ||