diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2013-01-21 01:47:39 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2013-01-21 01:47:57 -0500 |
commit | 373d4d099761cb1f637bed488ab3871945882273 (patch) | |
tree | 954bef7bc724aee105dd246d5f2b1ea04ed38b20 /kernel | |
parent | 64748a2c9062da0c32b59c1b368a86fc4613b1e1 (diff) |
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>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/module.c | 26 | ||||
-rw-r--r-- | kernel/panic.c | 34 | ||||
-rw-r--r-- | kernel/sched/core.c | 2 | ||||
-rw-r--r-- | kernel/sysctl.c | 2 |
4 files changed, 31 insertions, 33 deletions
diff --git a/kernel/module.c b/kernel/module.c index e69a5a68766f..cc000dd6e4a8 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -197,9 +197,10 @@ static inline int strong_try_module_get(struct module *mod) | |||
197 | return -ENOENT; | 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 | mod->taints |= (1U << flag); | 204 | mod->taints |= (1U << flag); |
204 | } | 205 | } |
205 | 206 | ||
@@ -727,7 +728,7 @@ static inline int try_force_unload(unsigned int flags) | |||
727 | { | 728 | { |
728 | int ret = (flags & O_TRUNC); | 729 | int ret = (flags & O_TRUNC); |
729 | if (ret) | 730 | if (ret) |
730 | add_taint(TAINT_FORCED_RMMOD); | 731 | add_taint(TAINT_FORCED_RMMOD, LOCKDEP_NOW_UNRELIABLE); |
731 | return ret; | 732 | return ret; |
732 | } | 733 | } |
733 | #else | 734 | #else |
@@ -1138,7 +1139,7 @@ static int try_to_force_load(struct module *mod, const char *reason) | |||
1138 | if (!test_taint(TAINT_FORCED_MODULE)) | 1139 | if (!test_taint(TAINT_FORCED_MODULE)) |
1139 | printk(KERN_WARNING "%s: %s: kernel tainted.\n", | 1140 | printk(KERN_WARNING "%s: %s: kernel tainted.\n", |
1140 | mod->name, reason); | 1141 | mod->name, reason); |
1141 | add_taint_module(mod, TAINT_FORCED_MODULE); | 1142 | add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_NOW_UNRELIABLE); |
1142 | return 0; | 1143 | return 0; |
1143 | #else | 1144 | #else |
1144 | return -ENOEXEC; | 1145 | return -ENOEXEC; |
@@ -2147,7 +2148,8 @@ static void set_license(struct module *mod, const char *license) | |||
2147 | if (!test_taint(TAINT_PROPRIETARY_MODULE)) | 2148 | if (!test_taint(TAINT_PROPRIETARY_MODULE)) |
2148 | printk(KERN_WARNING "%s: module license '%s' taints " | 2149 | printk(KERN_WARNING "%s: module license '%s' taints " |
2149 | "kernel.\n", mod->name, license); | 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 | ||
@@ -2700,10 +2702,10 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) | |||
2700 | } | 2702 | } |
2701 | 2703 | ||
2702 | if (!get_modinfo(info, "intree")) | 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 | if (get_modinfo(info, "staging")) { | 2707 | if (get_modinfo(info, "staging")) { |
2706 | add_taint_module(mod, TAINT_CRAP); | 2708 | add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK); |
2707 | printk(KERN_WARNING "%s: module is from the staging directory," | 2709 | printk(KERN_WARNING "%s: module is from the staging directory," |
2708 | " the quality is unknown, you have been warned.\n", | 2710 | " the quality is unknown, you have been warned.\n", |
2709 | mod->name); | 2711 | mod->name); |
@@ -2869,15 +2871,17 @@ static int check_module_license_and_versions(struct module *mod) | |||
2869 | * using GPL-only symbols it needs. | 2871 | * using GPL-only symbols it needs. |
2870 | */ | 2872 | */ |
2871 | if (strcmp(mod->name, "ndiswrapper") == 0) | 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 | /* driverloader was caught wrongly pretending to be under GPL */ | 2876 | /* driverloader was caught wrongly pretending to be under GPL */ |
2875 | if (strcmp(mod->name, "driverloader") == 0) | 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 | /* lve claims to be GPL but upstream won't provide source */ | 2881 | /* lve claims to be GPL but upstream won't provide source */ |
2879 | if (strcmp(mod->name, "lve") == 0) | 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 | #ifdef CONFIG_MODVERSIONS | 2886 | #ifdef CONFIG_MODVERSIONS |
2883 | if ((mod->num_syms && !mod->crcs) | 2887 | if ((mod->num_syms && !mod->crcs) |
@@ -3197,7 +3201,7 @@ again: | |||
3197 | "%s: module verification failed: signature and/or" | 3201 | "%s: module verification failed: signature and/or" |
3198 | " required key missing - tainting kernel\n", | 3202 | " required key missing - tainting kernel\n", |
3199 | mod->name); | 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 | #endif | 3206 | #endif |
3203 | 3207 | ||
diff --git a/kernel/panic.c b/kernel/panic.c index e1b2822fff97..7c57cc9eee2c 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -259,26 +259,19 @@ unsigned long get_taint(void) | |||
259 | return tainted_mask; | 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 | /* | 272 | if (lockdep_ok == LOCKDEP_NOW_UNRELIABLE && __debug_locks_off()) |
265 | * Can't trust the integrity of the kernel anymore. | 273 | printk(KERN_WARNING |
266 | * We don't call directly debug_locks_off() because the issue | 274 | "Disabling lock debugging due to kernel taint\n"); |
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; | ||
277 | |||
278 | default: | ||
279 | if (__debug_locks_off()) | ||
280 | printk(KERN_WARNING "Disabling lock debugging due to kernel taint\n"); | ||
281 | } | ||
282 | 275 | ||
283 | set_bit(flag, &tainted_mask); | 276 | set_bit(flag, &tainted_mask); |
284 | } | 277 | } |
@@ -421,7 +414,8 @@ static void warn_slowpath_common(const char *file, int line, void *caller, | |||
421 | print_modules(); | 414 | print_modules(); |
422 | dump_stack(); | 415 | dump_stack(); |
423 | print_oops_end_marker(); | 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 | void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) | 421 | void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 257002c13bb0..662f3d512183 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -2785,7 +2785,7 @@ static noinline void __schedule_bug(struct task_struct *prev) | |||
2785 | if (irqs_disabled()) | 2785 | if (irqs_disabled()) |
2786 | print_irqtrace_events(prev); | 2786 | print_irqtrace_events(prev); |
2787 | dump_stack(); | 2787 | dump_stack(); |
2788 | add_taint(TAINT_WARN); | 2788 | add_taint(TAINT_WARN, LOCKDEP_STILL_OK); |
2789 | } | 2789 | } |
2790 | 2790 | ||
2791 | /* | 2791 | /* |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c88878db491e..f97f9d75cde8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -2006,7 +2006,7 @@ static int proc_taint(struct ctl_table *table, int write, | |||
2006 | int i; | 2006 | int i; |
2007 | for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) { | 2007 | for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) { |
2008 | if ((tmptaint >> i) & 1) | 2008 | if ((tmptaint >> i) & 1) |
2009 | add_taint(i); | 2009 | add_taint(i, LOCKDEP_STILL_OK); |
2010 | } | 2010 | } |
2011 | } | 2011 | } |
2012 | 2012 | ||