Commit 373d4d099761cb1f637bed488ab3871945882273
1 parent
64748a2c90
Exists in
master
and in
20 other branches
taint: add explicit flag to show whether lock dep is still OK.
Fix up all callers as they were before, with make one change: an unsigned module taints the kernel, but doesn't turn off lockdep. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Showing 37 changed files with 69 additions and 67 deletions Side-by-side Diff
- arch/alpha/kernel/traps.c
- arch/arm/kernel/traps.c
- arch/arm64/kernel/traps.c
- arch/avr32/kernel/traps.c
- arch/hexagon/kernel/traps.c
- arch/ia64/kernel/traps.c
- arch/m68k/kernel/traps.c
- arch/mips/kernel/traps.c
- arch/parisc/kernel/traps.c
- arch/powerpc/kernel/traps.c
- arch/s390/kernel/traps.c
- arch/sh/kernel/traps.c
- arch/sparc/kernel/setup_64.c
- arch/sparc/kernel/traps_32.c
- arch/sparc/kernel/traps_64.c
- arch/unicore32/kernel/traps.c
- arch/x86/kernel/cpu/amd.c
- arch/x86/kernel/cpu/mcheck/mce.c
- arch/x86/kernel/cpu/mcheck/p5.c
- arch/x86/kernel/cpu/mcheck/winchip.c
- arch/x86/kernel/cpu/mtrr/generic.c
- arch/x86/kernel/dumpstack.c
- arch/xtensa/kernel/traps.c
- drivers/acpi/custom_method.c
- drivers/acpi/osl.c
- drivers/base/regmap/regmap-debugfs.c
- include/linux/kernel.h
- kernel/module.c
- kernel/panic.c
- kernel/sched/core.c
- kernel/sysctl.c
- lib/bug.c
- mm/memory.c
- mm/page_alloc.c
- mm/slab.c
- mm/slub.c
- sound/soc/soc-core.c
arch/alpha/kernel/traps.c
... | ... | @@ -186,7 +186,7 @@ |
186 | 186 | #endif |
187 | 187 | printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err); |
188 | 188 | dik_show_regs(regs, r9_15); |
189 | - add_taint(TAINT_DIE); | |
189 | + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); | |
190 | 190 | dik_show_trace((unsigned long *)(regs+1)); |
191 | 191 | dik_show_code((unsigned int *)regs->pc); |
192 | 192 |
arch/arm/kernel/traps.c
arch/arm64/kernel/traps.c
arch/avr32/kernel/traps.c
... | ... | @@ -61,7 +61,7 @@ |
61 | 61 | show_regs_log_lvl(regs, KERN_EMERG); |
62 | 62 | show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG); |
63 | 63 | bust_spinlocks(0); |
64 | - add_taint(TAINT_DIE); | |
64 | + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); | |
65 | 65 | spin_unlock_irq(&die_lock); |
66 | 66 | |
67 | 67 | if (in_interrupt()) |
arch/hexagon/kernel/traps.c
arch/ia64/kernel/traps.c
arch/m68k/kernel/traps.c
arch/mips/kernel/traps.c
arch/parisc/kernel/traps.c
arch/powerpc/kernel/traps.c
arch/s390/kernel/traps.c
arch/sh/kernel/traps.c
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/traps_32.c
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 | |
59 | 59 | printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter); |
60 | 60 | show_regs(regs); |
61 | - add_taint(TAINT_DIE); | |
61 | + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); | |
62 | 62 | |
63 | 63 | __SAVE; __SAVE; __SAVE; __SAVE; |
64 | 64 | __SAVE; __SAVE; __SAVE; __SAVE; |
arch/sparc/kernel/traps_64.c
... | ... | @@ -2383,7 +2383,7 @@ |
2383 | 2383 | notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV); |
2384 | 2384 | __asm__ __volatile__("flushw"); |
2385 | 2385 | show_regs(regs); |
2386 | - add_taint(TAINT_DIE); | |
2386 | + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); | |
2387 | 2387 | if (regs->tstate & TSTATE_PRIV) { |
2388 | 2388 | struct thread_info *tp = current_thread_info(); |
2389 | 2389 | struct reg_window *rw = (struct reg_window *) |
arch/unicore32/kernel/traps.c
arch/x86/kernel/cpu/amd.c
... | ... | @@ -220,8 +220,7 @@ |
220 | 220 | */ |
221 | 221 | WARN_ONCE(1, "WARNING: This combination of AMD" |
222 | 222 | " processors is not suitable for SMP.\n"); |
223 | - if (!test_taint(TAINT_UNSAFE_SMP)) | |
224 | - add_taint(TAINT_UNSAFE_SMP); | |
223 | + add_taint(TAINT_UNSAFE_SMP, LOCKDEP_NOW_UNRELIABLE); | |
225 | 224 | |
226 | 225 | valid_k7: |
227 | 226 | ; |
arch/x86/kernel/cpu/mcheck/mce.c
... | ... | @@ -1085,7 +1085,7 @@ |
1085 | 1085 | /* |
1086 | 1086 | * Set taint even when machine check was not enabled. |
1087 | 1087 | */ |
1088 | - add_taint(TAINT_MACHINE_CHECK); | |
1088 | + add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); | |
1089 | 1089 | |
1090 | 1090 | severity = mce_severity(&m, cfg->tolerant, NULL); |
1091 | 1091 |
arch/x86/kernel/cpu/mcheck/p5.c
arch/x86/kernel/cpu/mcheck/winchip.c
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | static void winchip_machine_check(struct pt_regs *regs, long error_code) |
16 | 16 | { |
17 | 17 | printk(KERN_EMERG "CPU0: Machine Check Exception.\n"); |
18 | - add_taint(TAINT_MACHINE_CHECK); | |
18 | + add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); | |
19 | 19 | } |
20 | 20 | |
21 | 21 | /* Set up machine check reporting on the Winchip C6 series */ |
arch/x86/kernel/cpu/mtrr/generic.c
... | ... | @@ -542,7 +542,7 @@ |
542 | 542 | |
543 | 543 | if (tmp != mask_lo) { |
544 | 544 | printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n"); |
545 | - add_taint(TAINT_FIRMWARE_WORKAROUND); | |
545 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
546 | 546 | mask_lo = tmp; |
547 | 547 | } |
548 | 548 | } |
arch/x86/kernel/dumpstack.c
arch/xtensa/kernel/traps.c
drivers/acpi/custom_method.c
drivers/acpi/osl.c
... | ... | @@ -661,7 +661,7 @@ |
661 | 661 | pr_warn(PREFIX |
662 | 662 | "Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n", |
663 | 663 | table->signature, table->oem_table_id); |
664 | - add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | |
664 | + add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE); | |
665 | 665 | } |
666 | 666 | |
667 | 667 |
drivers/base/regmap/regmap-debugfs.c
include/linux/kernel.h
... | ... | @@ -398,7 +398,11 @@ |
398 | 398 | extern int panic_on_io_nmi; |
399 | 399 | extern int sysctl_panic_on_stackoverflow; |
400 | 400 | extern const char *print_tainted(void); |
401 | -extern void add_taint(unsigned flag); | |
401 | +enum lockdep_ok { | |
402 | + LOCKDEP_STILL_OK, | |
403 | + LOCKDEP_NOW_UNRELIABLE | |
404 | +}; | |
405 | +extern void add_taint(unsigned flag, enum lockdep_ok); | |
402 | 406 | extern int test_taint(unsigned flag); |
403 | 407 | extern unsigned long get_taint(void); |
404 | 408 | extern int root_mountflags; |
kernel/module.c
... | ... | @@ -197,9 +197,10 @@ |
197 | 197 | return -ENOENT; |
198 | 198 | } |
199 | 199 | |
200 | -static inline void add_taint_module(struct module *mod, unsigned flag) | |
200 | +static inline void add_taint_module(struct module *mod, unsigned flag, | |
201 | + enum lockdep_ok lockdep_ok) | |
201 | 202 | { |
202 | - add_taint(flag); | |
203 | + add_taint(flag, lockdep_ok); | |
203 | 204 | mod->taints |= (1U << flag); |
204 | 205 | } |
205 | 206 | |
... | ... | @@ -727,7 +728,7 @@ |
727 | 728 | { |
728 | 729 | int ret = (flags & O_TRUNC); |
729 | 730 | if (ret) |
730 | - add_taint(TAINT_FORCED_RMMOD); | |
731 | + add_taint(TAINT_FORCED_RMMOD, LOCKDEP_NOW_UNRELIABLE); | |
731 | 732 | return ret; |
732 | 733 | } |
733 | 734 | #else |
... | ... | @@ -1138,7 +1139,7 @@ |
1138 | 1139 | if (!test_taint(TAINT_FORCED_MODULE)) |
1139 | 1140 | printk(KERN_WARNING "%s: %s: kernel tainted.\n", |
1140 | 1141 | mod->name, reason); |
1141 | - add_taint_module(mod, TAINT_FORCED_MODULE); | |
1142 | + add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_NOW_UNRELIABLE); | |
1142 | 1143 | return 0; |
1143 | 1144 | #else |
1144 | 1145 | return -ENOEXEC; |
... | ... | @@ -2147,7 +2148,8 @@ |
2147 | 2148 | if (!test_taint(TAINT_PROPRIETARY_MODULE)) |
2148 | 2149 | printk(KERN_WARNING "%s: module license '%s' taints " |
2149 | 2150 | "kernel.\n", mod->name, license); |
2150 | - add_taint_module(mod, TAINT_PROPRIETARY_MODULE); | |
2151 | + add_taint_module(mod, TAINT_PROPRIETARY_MODULE, | |
2152 | + LOCKDEP_NOW_UNRELIABLE); | |
2151 | 2153 | } |
2152 | 2154 | } |
2153 | 2155 | |
2154 | 2156 | |
... | ... | @@ -2700,10 +2702,10 @@ |
2700 | 2702 | } |
2701 | 2703 | |
2702 | 2704 | if (!get_modinfo(info, "intree")) |
2703 | - add_taint_module(mod, TAINT_OOT_MODULE); | |
2705 | + add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); | |
2704 | 2706 | |
2705 | 2707 | if (get_modinfo(info, "staging")) { |
2706 | - add_taint_module(mod, TAINT_CRAP); | |
2708 | + add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK); | |
2707 | 2709 | printk(KERN_WARNING "%s: module is from the staging directory," |
2708 | 2710 | " the quality is unknown, you have been warned.\n", |
2709 | 2711 | mod->name); |
2710 | 2712 | |
2711 | 2713 | |
... | ... | @@ -2869,15 +2871,17 @@ |
2869 | 2871 | * using GPL-only symbols it needs. |
2870 | 2872 | */ |
2871 | 2873 | if (strcmp(mod->name, "ndiswrapper") == 0) |
2872 | - add_taint(TAINT_PROPRIETARY_MODULE); | |
2874 | + add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_NOW_UNRELIABLE); | |
2873 | 2875 | |
2874 | 2876 | /* driverloader was caught wrongly pretending to be under GPL */ |
2875 | 2877 | if (strcmp(mod->name, "driverloader") == 0) |
2876 | - add_taint_module(mod, TAINT_PROPRIETARY_MODULE); | |
2878 | + add_taint_module(mod, TAINT_PROPRIETARY_MODULE, | |
2879 | + LOCKDEP_NOW_UNRELIABLE); | |
2877 | 2880 | |
2878 | 2881 | /* lve claims to be GPL but upstream won't provide source */ |
2879 | 2882 | if (strcmp(mod->name, "lve") == 0) |
2880 | - add_taint_module(mod, TAINT_PROPRIETARY_MODULE); | |
2883 | + add_taint_module(mod, TAINT_PROPRIETARY_MODULE, | |
2884 | + LOCKDEP_NOW_UNRELIABLE); | |
2881 | 2885 | |
2882 | 2886 | #ifdef CONFIG_MODVERSIONS |
2883 | 2887 | if ((mod->num_syms && !mod->crcs) |
... | ... | @@ -3197,7 +3201,7 @@ |
3197 | 3201 | "%s: module verification failed: signature and/or" |
3198 | 3202 | " required key missing - tainting kernel\n", |
3199 | 3203 | mod->name); |
3200 | - add_taint_module(mod, TAINT_FORCED_MODULE); | |
3204 | + add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_STILL_OK); | |
3201 | 3205 | } |
3202 | 3206 | #endif |
3203 | 3207 |
kernel/panic.c
... | ... | @@ -259,27 +259,20 @@ |
259 | 259 | return tainted_mask; |
260 | 260 | } |
261 | 261 | |
262 | -void add_taint(unsigned flag) | |
262 | +/** | |
263 | + * add_taint: add a taint flag if not already set. | |
264 | + * @flag: one of the TAINT_* constants. | |
265 | + * @lockdep_ok: whether lock debugging is still OK. | |
266 | + * | |
267 | + * If something bad has gone wrong, you'll want @lockdebug_ok = false, but for | |
268 | + * some notewortht-but-not-corrupting cases, it can be set to true. | |
269 | + */ | |
270 | +void add_taint(unsigned flag, enum lockdep_ok lockdep_ok) | |
263 | 271 | { |
264 | - /* | |
265 | - * Can't trust the integrity of the kernel anymore. | |
266 | - * We don't call directly debug_locks_off() because the issue | |
267 | - * is not necessarily serious enough to set oops_in_progress to 1 | |
268 | - * Also we want to keep up lockdep for staging/out-of-tree | |
269 | - * development and post-warning case. | |
270 | - */ | |
271 | - switch (flag) { | |
272 | - case TAINT_CRAP: | |
273 | - case TAINT_OOT_MODULE: | |
274 | - case TAINT_WARN: | |
275 | - case TAINT_FIRMWARE_WORKAROUND: | |
276 | - break; | |
272 | + if (lockdep_ok == LOCKDEP_NOW_UNRELIABLE && __debug_locks_off()) | |
273 | + printk(KERN_WARNING | |
274 | + "Disabling lock debugging due to kernel taint\n"); | |
277 | 275 | |
278 | - default: | |
279 | - if (__debug_locks_off()) | |
280 | - printk(KERN_WARNING "Disabling lock debugging due to kernel taint\n"); | |
281 | - } | |
282 | - | |
283 | 276 | set_bit(flag, &tainted_mask); |
284 | 277 | } |
285 | 278 | EXPORT_SYMBOL(add_taint); |
... | ... | @@ -421,7 +414,8 @@ |
421 | 414 | print_modules(); |
422 | 415 | dump_stack(); |
423 | 416 | print_oops_end_marker(); |
424 | - add_taint(taint); | |
417 | + /* Just a warning, don't kill lockdep. */ | |
418 | + add_taint(taint, LOCKDEP_STILL_OK); | |
425 | 419 | } |
426 | 420 | |
427 | 421 | void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) |
kernel/sched/core.c
kernel/sysctl.c
lib/bug.c
... | ... | @@ -166,7 +166,8 @@ |
166 | 166 | print_modules(); |
167 | 167 | show_regs(regs); |
168 | 168 | print_oops_end_marker(); |
169 | - add_taint(BUG_GET_TAINT(bug)); | |
169 | + /* Just a warning, don't kill lockdep. */ | |
170 | + add_taint(BUG_GET_TAINT(bug), LOCKDEP_STILL_OK); | |
170 | 171 | return BUG_TRAP_TYPE_WARN; |
171 | 172 | } |
172 | 173 |
mm/memory.c
... | ... | @@ -716,7 +716,7 @@ |
716 | 716 | print_symbol(KERN_ALERT "vma->vm_file->f_op->mmap: %s\n", |
717 | 717 | (unsigned long)vma->vm_file->f_op->mmap); |
718 | 718 | dump_stack(); |
719 | - add_taint(TAINT_BAD_PAGE); | |
719 | + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); | |
720 | 720 | } |
721 | 721 | |
722 | 722 | static inline bool is_cow_mapping(vm_flags_t flags) |
mm/page_alloc.c
mm/slab.c
mm/slub.c
... | ... | @@ -562,7 +562,7 @@ |
562 | 562 | printk(KERN_ERR "----------------------------------------" |
563 | 563 | "-------------------------------------\n\n"); |
564 | 564 | |
565 | - add_taint(TAINT_BAD_PAGE); | |
565 | + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); | |
566 | 566 | } |
567 | 567 | |
568 | 568 | static void slab_fix(struct kmem_cache *s, char *fmt, ...) |
sound/soc/soc-core.c