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