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>
This commit is contained in:
Родитель
74489a91dd
Коммит
bcdcd8e725
|
@ -251,6 +251,8 @@ characters, each representing a particular tainted value.
|
|||
7: 'U' if a user or user application specifically requested that the
|
||||
Tainted flag be set, ' ' otherwise.
|
||||
|
||||
8: 'D' if the kernel has died recently, i.e. there was an OOPS or BUG.
|
||||
|
||||
The primary reason for the 'Tainted: ' string is to tell kernel
|
||||
debuggers if this is a clean kernel or if anything unusual has
|
||||
occurred. Tainting is permanent: even if an offending module is
|
||||
|
|
|
@ -184,6 +184,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
|
|||
#endif
|
||||
printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
|
||||
dik_show_regs(regs, r9_15);
|
||||
add_taint(TAINT_DIE);
|
||||
dik_show_trace((unsigned long *)(regs+1));
|
||||
dik_show_code((unsigned int *)regs->pc);
|
||||
|
||||
|
|
|
@ -249,6 +249,7 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
|||
bust_spinlocks(1);
|
||||
__die(str, err, thread, regs);
|
||||
bust_spinlocks(0);
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die_lock);
|
||||
|
||||
if (in_interrupt())
|
||||
|
|
|
@ -185,6 +185,7 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
|||
printk("Internal error: %s: %x\n", str, err);
|
||||
printk("CPU: %d\n", smp_processor_id());
|
||||
show_regs(regs);
|
||||
add_taint(TAINT_DIE);
|
||||
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
|
||||
current->comm, current->pid, end_of_stack(tsk));
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ void NORET_TYPE die(const char *str, struct pt_regs *regs, long err)
|
|||
show_regs_log_lvl(regs, KERN_EMERG);
|
||||
show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG);
|
||||
bust_spinlocks(0);
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die_lock);
|
||||
|
||||
if (in_interrupt())
|
||||
|
|
|
@ -433,6 +433,7 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||
|
||||
bust_spinlocks(0);
|
||||
die.lock_owner = -1;
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irqrestore(&die.lock, flags);
|
||||
|
||||
if (!regs)
|
||||
|
|
|
@ -69,6 +69,7 @@ die (const char *str, struct pt_regs *regs, long err)
|
|||
|
||||
bust_spinlocks(0);
|
||||
die.lock_owner = -1;
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die.lock);
|
||||
|
||||
if (panic_on_oops)
|
||||
|
|
|
@ -1170,6 +1170,7 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
|
|||
console_verbose();
|
||||
printk("%s: %08x\n",str,nr);
|
||||
show_registers(fp);
|
||||
add_taint(TAINT_DIE);
|
||||
do_exit(SIGSEGV);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ void die_if_kernel(char *str, struct pt_regs *fp, int nr)
|
|||
printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
|
||||
current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
|
||||
show_stack(NULL, (unsigned long *)fp);
|
||||
add_taint(TAINT_DIE);
|
||||
do_exit(SIGSEGV);
|
||||
}
|
||||
|
||||
|
|
|
@ -326,6 +326,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
|
|||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
printk("%s[#%d]:\n", str, ++die_counter);
|
||||
show_registers(regs);
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die_lock);
|
||||
|
||||
if (in_interrupt())
|
||||
|
|
|
@ -264,6 +264,7 @@ KERN_CRIT " || ||\n");
|
|||
|
||||
show_regs(regs);
|
||||
dump_stack();
|
||||
add_taint(TAINT_DIE);
|
||||
|
||||
if (in_interrupt())
|
||||
panic("Fatal exception in interrupt");
|
||||
|
|
|
@ -149,6 +149,7 @@ int die(const char *str, struct pt_regs *regs, long err)
|
|||
|
||||
bust_spinlocks(0);
|
||||
die.lock_owner = -1;
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irqrestore(&die.lock, flags);
|
||||
|
||||
if (kexec_should_crash(current) ||
|
||||
|
|
|
@ -92,6 +92,7 @@ int die(const char * str, struct pt_regs * fp, long err)
|
|||
if (nl)
|
||||
printk("\n");
|
||||
show_regs(fp);
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die_lock);
|
||||
/* do_exit() should take care of panic'ing from an interrupt
|
||||
* context so we don't handle it here
|
||||
|
|
|
@ -262,6 +262,7 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||
print_modules();
|
||||
show_regs(regs);
|
||||
bust_spinlocks(0);
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die_lock);
|
||||
if (in_interrupt())
|
||||
panic("Fatal exception in interrupt");
|
||||
|
|
|
@ -103,6 +103,7 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||
(unsigned long)task_stack_page(current));
|
||||
|
||||
bust_spinlocks(0);
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die_lock);
|
||||
|
||||
if (kexec_should_crash(current))
|
||||
|
|
|
@ -101,6 +101,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||
|
||||
printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
|
||||
show_regs(regs);
|
||||
add_taint(TAINT_DIE);
|
||||
|
||||
__SAVE; __SAVE; __SAVE; __SAVE;
|
||||
__SAVE; __SAVE; __SAVE; __SAVE;
|
||||
|
|
|
@ -2225,6 +2225,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||
notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
|
||||
__asm__ __volatile__("flushw");
|
||||
__show_regs(regs);
|
||||
add_taint(TAINT_DIE);
|
||||
if (regs->tstate & TSTATE_PRIV) {
|
||||
struct reg_window *rw = (struct reg_window *)
|
||||
(regs->u_regs[UREG_FP] + STACK_BIAS);
|
||||
|
|
|
@ -518,6 +518,7 @@ void __kprobes __die(const char * str, struct pt_regs * regs, long err)
|
|||
printk("\n");
|
||||
notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
|
||||
show_registers(regs);
|
||||
add_taint(TAINT_DIE);
|
||||
/* Executive summary in case the oops scrolled away */
|
||||
printk(KERN_ALERT "RIP ");
|
||||
printk_address(regs->rip);
|
||||
|
|
|
@ -482,6 +482,7 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||
if (!user_mode(regs))
|
||||
show_stack(NULL, (unsigned long*)regs->areg[1]);
|
||||
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die_lock);
|
||||
|
||||
if (in_interrupt())
|
||||
|
|
|
@ -210,6 +210,7 @@ extern enum system_states {
|
|||
#define TAINT_MACHINE_CHECK (1<<4)
|
||||
#define TAINT_BAD_PAGE (1<<5)
|
||||
#define TAINT_USER (1<<6)
|
||||
#define TAINT_DIE (1<<7)
|
||||
|
||||
extern void dump_stack(void);
|
||||
|
||||
|
|
|
@ -159,14 +159,15 @@ const char *print_tainted(void)
|
|||
{
|
||||
static char buf[20];
|
||||
if (tainted) {
|
||||
snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c",
|
||||
snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c",
|
||||
tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
|
||||
tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
|
||||
tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
|
||||
tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
|
||||
tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
|
||||
tainted & TAINT_BAD_PAGE ? 'B' : ' ',
|
||||
tainted & TAINT_USER ? 'U' : ' ');
|
||||
tainted & TAINT_USER ? 'U' : ' ',
|
||||
tainted & TAINT_DIE ? 'D' : ' ');
|
||||
}
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "Not tainted");
|
||||
|
|
Загрузка…
Ссылка в новой задаче