diff options
author | Pavel Emelianov <xemul@openvz.org> | 2007-07-17 07:03:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-17 13:23:02 -0400 |
commit | bcdcd8e725b923ad7c0de809680d5d5658a7bf8c (patch) | |
tree | f8fe86531df3bd96c0d8fd2d7a8fb1a6639261db | |
parent | 74489a91dd43aecd638709d34a2f58b91cfda5cf (diff) |
Report that kernel is tainted if there was an OOPS
If the kernel OOPSed or BUGed then it probably should be considered as
tainted. Thus, all subsequent OOPSes and SysRq dumps will report the
tainted kernel. This saves a lot of time explaining oddities in the
calltraces.
Signed-off-by: Pavel Emelianov <xemul@openvz.org>
Acked-by: Randy Dunlap <randy.dunlap@oracle.com>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ Added parisc patch from Matthew Wilson -Linus ]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/oops-tracing.txt | 2 | ||||
-rw-r--r-- | arch/alpha/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/arm26/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/avr32/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/m68k/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/m68knommu/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/parisc/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/ppc/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/sh/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/x86_64/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/xtensa/kernel/traps.c | 1 | ||||
-rw-r--r-- | include/linux/kernel.h | 1 | ||||
-rw-r--r-- | kernel/panic.c | 5 |
21 files changed, 24 insertions, 2 deletions
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt index 23e6dde7eea6..7f60dfe642ca 100644 --- a/Documentation/oops-tracing.txt +++ b/Documentation/oops-tracing.txt | |||
@@ -251,6 +251,8 @@ characters, each representing a particular tainted value. | |||
251 | 7: 'U' if a user or user application specifically requested that the | 251 | 7: 'U' if a user or user application specifically requested that the |
252 | Tainted flag be set, ' ' otherwise. | 252 | Tainted flag be set, ' ' otherwise. |
253 | 253 | ||
254 | 8: 'D' if the kernel has died recently, i.e. there was an OOPS or BUG. | ||
255 | |||
254 | The primary reason for the 'Tainted: ' string is to tell kernel | 256 | The primary reason for the 'Tainted: ' string is to tell kernel |
255 | debuggers if this is a clean kernel or if anything unusual has | 257 | debuggers if this is a clean kernel or if anything unusual has |
256 | occurred. Tainting is permanent: even if an offending module is | 258 | occurred. Tainting is permanent: even if an offending module is |
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index d6e665d567bd..ec0f05e0d8ff 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c | |||
@@ -184,6 +184,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15) | |||
184 | #endif | 184 | #endif |
185 | printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err); | 185 | printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err); |
186 | dik_show_regs(regs, r9_15); | 186 | dik_show_regs(regs, r9_15); |
187 | add_taint(TAINT_DIE); | ||
187 | dik_show_trace((unsigned long *)(regs+1)); | 188 | dik_show_trace((unsigned long *)(regs+1)); |
188 | dik_show_code((unsigned int *)regs->pc); | 189 | dik_show_code((unsigned int *)regs->pc); |
189 | 190 | ||
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 237f4999b9a1..f2114bcf09d5 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -249,6 +249,7 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) | |||
249 | bust_spinlocks(1); | 249 | bust_spinlocks(1); |
250 | __die(str, err, thread, regs); | 250 | __die(str, err, thread, regs); |
251 | bust_spinlocks(0); | 251 | bust_spinlocks(0); |
252 | add_taint(TAINT_DIE); | ||
252 | spin_unlock_irq(&die_lock); | 253 | spin_unlock_irq(&die_lock); |
253 | 254 | ||
254 | if (in_interrupt()) | 255 | if (in_interrupt()) |
diff --git a/arch/arm26/kernel/traps.c b/arch/arm26/kernel/traps.c index d594fb59e945..2911e2eae80e 100644 --- a/arch/arm26/kernel/traps.c +++ b/arch/arm26/kernel/traps.c | |||
@@ -185,6 +185,7 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) | |||
185 | printk("Internal error: %s: %x\n", str, err); | 185 | printk("Internal error: %s: %x\n", str, err); |
186 | printk("CPU: %d\n", smp_processor_id()); | 186 | printk("CPU: %d\n", smp_processor_id()); |
187 | show_regs(regs); | 187 | show_regs(regs); |
188 | add_taint(TAINT_DIE); | ||
188 | printk("Process %s (pid: %d, stack limit = 0x%p)\n", | 189 | printk("Process %s (pid: %d, stack limit = 0x%p)\n", |
189 | current->comm, current->pid, end_of_stack(tsk)); | 190 | current->comm, current->pid, end_of_stack(tsk)); |
190 | 191 | ||
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c index aaa792815cd7..9a73ce7eb50f 100644 --- a/arch/avr32/kernel/traps.c +++ b/arch/avr32/kernel/traps.c | |||
@@ -56,6 +56,7 @@ void NORET_TYPE die(const char *str, struct pt_regs *regs, long err) | |||
56 | show_regs_log_lvl(regs, KERN_EMERG); | 56 | show_regs_log_lvl(regs, KERN_EMERG); |
57 | show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG); | 57 | show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG); |
58 | bust_spinlocks(0); | 58 | bust_spinlocks(0); |
59 | add_taint(TAINT_DIE); | ||
59 | spin_unlock_irq(&die_lock); | 60 | spin_unlock_irq(&die_lock); |
60 | 61 | ||
61 | if (in_interrupt()) | 62 | if (in_interrupt()) |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 28bd1c5163ec..18c1c285836d 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -433,6 +433,7 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
433 | 433 | ||
434 | bust_spinlocks(0); | 434 | bust_spinlocks(0); |
435 | die.lock_owner = -1; | 435 | die.lock_owner = -1; |
436 | add_taint(TAINT_DIE); | ||
436 | spin_unlock_irqrestore(&die.lock, flags); | 437 | spin_unlock_irqrestore(&die.lock, flags); |
437 | 438 | ||
438 | if (!regs) | 439 | if (!regs) |
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 15ad85da15a9..3aeaf15e468b 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
@@ -69,6 +69,7 @@ die (const char *str, struct pt_regs *regs, long err) | |||
69 | 69 | ||
70 | bust_spinlocks(0); | 70 | bust_spinlocks(0); |
71 | die.lock_owner = -1; | 71 | die.lock_owner = -1; |
72 | add_taint(TAINT_DIE); | ||
72 | spin_unlock_irq(&die.lock); | 73 | spin_unlock_irq(&die.lock); |
73 | 74 | ||
74 | if (panic_on_oops) | 75 | if (panic_on_oops) |
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index a27a4fa33296..4e2752a0e89b 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c | |||
@@ -1170,6 +1170,7 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr) | |||
1170 | console_verbose(); | 1170 | console_verbose(); |
1171 | printk("%s: %08x\n",str,nr); | 1171 | printk("%s: %08x\n",str,nr); |
1172 | show_registers(fp); | 1172 | show_registers(fp); |
1173 | add_taint(TAINT_DIE); | ||
1173 | do_exit(SIGSEGV); | 1174 | do_exit(SIGSEGV); |
1174 | } | 1175 | } |
1175 | 1176 | ||
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c index bed5f47bf568..fde04e1757f7 100644 --- a/arch/m68knommu/kernel/traps.c +++ b/arch/m68knommu/kernel/traps.c | |||
@@ -83,6 +83,7 @@ void die_if_kernel(char *str, struct pt_regs *fp, int nr) | |||
83 | printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n", | 83 | printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n", |
84 | current->comm, current->pid, PAGE_SIZE+(unsigned long)current); | 84 | current->comm, current->pid, PAGE_SIZE+(unsigned long)current); |
85 | show_stack(NULL, (unsigned long *)fp); | 85 | show_stack(NULL, (unsigned long *)fp); |
86 | add_taint(TAINT_DIE); | ||
86 | do_exit(SIGSEGV); | 87 | do_exit(SIGSEGV); |
87 | } | 88 | } |
88 | 89 | ||
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 37c562c4c817..ce277cb34dd0 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -326,6 +326,7 @@ void __noreturn die(const char * str, struct pt_regs * regs) | |||
326 | #endif /* CONFIG_MIPS_MT_SMTC */ | 326 | #endif /* CONFIG_MIPS_MT_SMTC */ |
327 | printk("%s[#%d]:\n", str, ++die_counter); | 327 | printk("%s[#%d]:\n", str, ++die_counter); |
328 | show_registers(regs); | 328 | show_registers(regs); |
329 | add_taint(TAINT_DIE); | ||
329 | spin_unlock_irq(&die_lock); | 330 | spin_unlock_irq(&die_lock); |
330 | 331 | ||
331 | if (in_interrupt()) | 332 | if (in_interrupt()) |
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index f9bca2d74b38..bbf029a184ac 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
@@ -264,6 +264,7 @@ KERN_CRIT " || ||\n"); | |||
264 | 264 | ||
265 | show_regs(regs); | 265 | show_regs(regs); |
266 | dump_stack(); | 266 | dump_stack(); |
267 | add_taint(TAINT_DIE); | ||
267 | 268 | ||
268 | if (in_interrupt()) | 269 | if (in_interrupt()) |
269 | panic("Fatal exception in interrupt"); | 270 | panic("Fatal exception in interrupt"); |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 3b8427e6283d..2bb1cb911783 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -149,6 +149,7 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
149 | 149 | ||
150 | bust_spinlocks(0); | 150 | bust_spinlocks(0); |
151 | die.lock_owner = -1; | 151 | die.lock_owner = -1; |
152 | add_taint(TAINT_DIE); | ||
152 | spin_unlock_irqrestore(&die.lock, flags); | 153 | spin_unlock_irqrestore(&die.lock, flags); |
153 | 154 | ||
154 | if (kexec_should_crash(current) || | 155 | if (kexec_should_crash(current) || |
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 0eaef7c8378b..3f3b292eb773 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
@@ -92,6 +92,7 @@ int die(const char * str, struct pt_regs * fp, long err) | |||
92 | if (nl) | 92 | if (nl) |
93 | printk("\n"); | 93 | printk("\n"); |
94 | show_regs(fp); | 94 | show_regs(fp); |
95 | add_taint(TAINT_DIE); | ||
95 | spin_unlock_irq(&die_lock); | 96 | spin_unlock_irq(&die_lock); |
96 | /* do_exit() should take care of panic'ing from an interrupt | 97 | /* do_exit() should take care of panic'ing from an interrupt |
97 | * context so we don't handle it here | 98 | * context so we don't handle it here |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 81e03b9c3841..8ec9def83ccb 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -262,6 +262,7 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
262 | print_modules(); | 262 | print_modules(); |
263 | show_regs(regs); | 263 | show_regs(regs); |
264 | bust_spinlocks(0); | 264 | bust_spinlocks(0); |
265 | add_taint(TAINT_DIE); | ||
265 | spin_unlock_irq(&die_lock); | 266 | spin_unlock_irq(&die_lock); |
266 | if (in_interrupt()) | 267 | if (in_interrupt()) |
267 | panic("Fatal exception in interrupt"); | 268 | panic("Fatal exception in interrupt"); |
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 05a40f3c30bf..502d43e4785c 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c | |||
@@ -103,6 +103,7 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
103 | (unsigned long)task_stack_page(current)); | 103 | (unsigned long)task_stack_page(current)); |
104 | 104 | ||
105 | bust_spinlocks(0); | 105 | bust_spinlocks(0); |
106 | add_taint(TAINT_DIE); | ||
106 | spin_unlock_irq(&die_lock); | 107 | spin_unlock_irq(&die_lock); |
107 | 108 | ||
108 | if (kexec_should_crash(current)) | 109 | if (kexec_should_crash(current)) |
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c index dc9ffea2a4f7..3bc3bff51e08 100644 --- a/arch/sparc/kernel/traps.c +++ b/arch/sparc/kernel/traps.c | |||
@@ -101,6 +101,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
101 | 101 | ||
102 | printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter); | 102 | printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter); |
103 | show_regs(regs); | 103 | show_regs(regs); |
104 | add_taint(TAINT_DIE); | ||
104 | 105 | ||
105 | __SAVE; __SAVE; __SAVE; __SAVE; | 106 | __SAVE; __SAVE; __SAVE; __SAVE; |
106 | __SAVE; __SAVE; __SAVE; __SAVE; | 107 | __SAVE; __SAVE; __SAVE; __SAVE; |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 00a9e3286c83..6ef2d299fb10 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -2225,6 +2225,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2225 | notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV); | 2225 | notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV); |
2226 | __asm__ __volatile__("flushw"); | 2226 | __asm__ __volatile__("flushw"); |
2227 | __show_regs(regs); | 2227 | __show_regs(regs); |
2228 | add_taint(TAINT_DIE); | ||
2228 | if (regs->tstate & TSTATE_PRIV) { | 2229 | if (regs->tstate & TSTATE_PRIV) { |
2229 | struct reg_window *rw = (struct reg_window *) | 2230 | struct reg_window *rw = (struct reg_window *) |
2230 | (regs->u_regs[UREG_FP] + STACK_BIAS); | 2231 | (regs->u_regs[UREG_FP] + STACK_BIAS); |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 7fa155c394d9..6963b64a76ca 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -518,6 +518,7 @@ void __kprobes __die(const char * str, struct pt_regs * regs, long err) | |||
518 | printk("\n"); | 518 | printk("\n"); |
519 | notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); | 519 | notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); |
520 | show_registers(regs); | 520 | show_registers(regs); |
521 | add_taint(TAINT_DIE); | ||
521 | /* Executive summary in case the oops scrolled away */ | 522 | /* Executive summary in case the oops scrolled away */ |
522 | printk(KERN_ALERT "RIP "); | 523 | printk(KERN_ALERT "RIP "); |
523 | printk_address(regs->rip); | 524 | printk_address(regs->rip); |
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 693ab268485e..c5e62f9d9f50 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c | |||
@@ -482,6 +482,7 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
482 | if (!user_mode(regs)) | 482 | if (!user_mode(regs)) |
483 | show_stack(NULL, (unsigned long*)regs->areg[1]); | 483 | show_stack(NULL, (unsigned long*)regs->areg[1]); |
484 | 484 | ||
485 | add_taint(TAINT_DIE); | ||
485 | spin_unlock_irq(&die_lock); | 486 | spin_unlock_irq(&die_lock); |
486 | 487 | ||
487 | if (in_interrupt()) | 488 | if (in_interrupt()) |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 7a4852505914..1eb9cde550c4 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -210,6 +210,7 @@ extern enum system_states { | |||
210 | #define TAINT_MACHINE_CHECK (1<<4) | 210 | #define TAINT_MACHINE_CHECK (1<<4) |
211 | #define TAINT_BAD_PAGE (1<<5) | 211 | #define TAINT_BAD_PAGE (1<<5) |
212 | #define TAINT_USER (1<<6) | 212 | #define TAINT_USER (1<<6) |
213 | #define TAINT_DIE (1<<7) | ||
213 | 214 | ||
214 | extern void dump_stack(void); | 215 | extern void dump_stack(void); |
215 | 216 | ||
diff --git a/kernel/panic.c b/kernel/panic.c index 623d1828259a..f64f4c1ac11f 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -159,14 +159,15 @@ const char *print_tainted(void) | |||
159 | { | 159 | { |
160 | static char buf[20]; | 160 | static char buf[20]; |
161 | if (tainted) { | 161 | if (tainted) { |
162 | snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c", | 162 | snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c", |
163 | tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', | 163 | tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', |
164 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', | 164 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', |
165 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', | 165 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', |
166 | tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', | 166 | tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', |
167 | tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', | 167 | tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', |
168 | tainted & TAINT_BAD_PAGE ? 'B' : ' ', | 168 | tainted & TAINT_BAD_PAGE ? 'B' : ' ', |
169 | tainted & TAINT_USER ? 'U' : ' '); | 169 | tainted & TAINT_USER ? 'U' : ' ', |
170 | tainted & TAINT_DIE ? 'D' : ' '); | ||
170 | } | 171 | } |
171 | else | 172 | else |
172 | snprintf(buf, sizeof(buf), "Not tainted"); | 173 | snprintf(buf, sizeof(buf), "Not tainted"); |