aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Emelianov <xemul@openvz.org>2007-07-17 07:03:42 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:02 -0400
commitbcdcd8e725b923ad7c0de809680d5d5658a7bf8c (patch)
treef8fe86531df3bd96c0d8fd2d7a8fb1a6639261db
parent74489a91dd43aecd638709d34a2f58b91cfda5cf (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.txt2
-rw-r--r--arch/alpha/kernel/traps.c1
-rw-r--r--arch/arm/kernel/traps.c1
-rw-r--r--arch/arm26/kernel/traps.c1
-rw-r--r--arch/avr32/kernel/traps.c1
-rw-r--r--arch/i386/kernel/traps.c1
-rw-r--r--arch/ia64/kernel/traps.c1
-rw-r--r--arch/m68k/kernel/traps.c1
-rw-r--r--arch/m68knommu/kernel/traps.c1
-rw-r--r--arch/mips/kernel/traps.c1
-rw-r--r--arch/parisc/kernel/traps.c1
-rw-r--r--arch/powerpc/kernel/traps.c1
-rw-r--r--arch/ppc/kernel/traps.c1
-rw-r--r--arch/s390/kernel/traps.c1
-rw-r--r--arch/sh/kernel/traps.c1
-rw-r--r--arch/sparc/kernel/traps.c1
-rw-r--r--arch/sparc64/kernel/traps.c1
-rw-r--r--arch/x86_64/kernel/traps.c1
-rw-r--r--arch/xtensa/kernel/traps.c1
-rw-r--r--include/linux/kernel.h1
-rw-r--r--kernel/panic.c5
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
254The primary reason for the 'Tainted: ' string is to tell kernel 256The primary reason for the 'Tainted: ' string is to tell kernel
255debuggers if this is a clean kernel or if anything unusual has 257debuggers if this is a clean kernel or if anything unusual has
256occurred. Tainting is permanent: even if an offending module is 258occurred. 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
214extern void dump_stack(void); 215extern 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");