diff options
Diffstat (limited to 'kernel/panic.c')
| -rw-r--r-- | kernel/panic.c | 46 | 
1 files changed, 33 insertions, 13 deletions
diff --git a/kernel/panic.c b/kernel/panic.c index b6c482ccc5d..62e16cef9cc 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -32,8 +32,9 @@ static unsigned long tainted_mask;  static int pause_on_oops;  static int pause_on_oops_flag;  static DEFINE_SPINLOCK(pause_on_oops_lock); +static bool crash_kexec_post_notifiers; -int panic_timeout; +int panic_timeout = CONFIG_PANIC_TIMEOUT;  EXPORT_SYMBOL_GPL(panic_timeout);  ATOMIC_NOTIFIER_HEAD(panic_notifier_list); @@ -100,7 +101,7 @@ void panic(const char *fmt, ...)  	va_start(args, fmt);  	vsnprintf(buf, sizeof(buf), fmt, args);  	va_end(args); -	printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); +	pr_emerg("Kernel panic - not syncing: %s\n", buf);  #ifdef CONFIG_DEBUG_BUGVERBOSE  	/*  	 * Avoid nested stack-dumping if a panic occurs during oops processing @@ -112,9 +113,11 @@ void panic(const char *fmt, ...)  	/*  	 * If we have crashed and we have a crash kernel loaded let it handle  	 * everything else. -	 * Do we want to call this before we try to display a message? +	 * If we want to run this after calling panic_notifiers, pass +	 * the "crash_kexec_post_notifiers" option to the kernel.  	 */ -	crash_kexec(NULL); +	if (!crash_kexec_post_notifiers) +		crash_kexec(NULL);  	/*  	 * Note smp_send_stop is the usual smp shutdown function, which @@ -131,6 +134,15 @@ void panic(const char *fmt, ...)  	kmsg_dump(KMSG_DUMP_PANIC); +	/* +	 * If you doubt kdump always works fine in any situation, +	 * "crash_kexec_post_notifiers" offers you a chance to run +	 * panic_notifiers and dumping kmsg before kdump. +	 * Note: since some panic_notifiers can make crashed kernel +	 * more unstable, it can increase risks of the kdump failure too. +	 */ +	crash_kexec(NULL); +  	bust_spinlocks(0);  	if (!panic_blink) @@ -141,7 +153,7 @@ void panic(const char *fmt, ...)  		 * Delay timeout seconds before rebooting the machine.  		 * We can't use the "normal" timers since we just panicked.  		 */ -		printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout); +		pr_emerg("Rebooting in %d seconds..", panic_timeout);  		for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) {  			touch_nmi_watchdog(); @@ -165,7 +177,7 @@ void panic(const char *fmt, ...)  		extern int stop_a_enabled;  		/* Make sure the user can actually press Stop-A (L1-A) */  		stop_a_enabled = 1; -		printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n"); +		pr_emerg("Press Stop-A (L1-A) to return to the boot prom\n");  	}  #endif  #if defined(CONFIG_S390) @@ -176,6 +188,7 @@ void panic(const char *fmt, ...)  		disabled_wait(caller);  	}  #endif +	pr_emerg("---[ end Kernel panic - not syncing: %s\n", buf);  	local_irq_enable();  	for (i = 0; ; i += PANIC_TIMER_STEP) {  		touch_softlockup_watchdog(); @@ -199,7 +212,7 @@ struct tnt {  static const struct tnt tnts[] = {  	{ TAINT_PROPRIETARY_MODULE,	'P', 'G' },  	{ TAINT_FORCED_MODULE,		'F', ' ' }, -	{ TAINT_UNSAFE_SMP,		'S', ' ' }, +	{ TAINT_CPU_OUT_OF_SPEC,	'S', ' ' },  	{ TAINT_FORCED_RMMOD,		'R', ' ' },  	{ TAINT_MACHINE_CHECK,		'M', ' ' },  	{ TAINT_BAD_PAGE,		'B', ' ' }, @@ -210,6 +223,7 @@ static const struct tnt tnts[] = {  	{ TAINT_CRAP,			'C', ' ' },  	{ TAINT_FIRMWARE_WORKAROUND,	'I', ' ' },  	{ TAINT_OOT_MODULE,		'O', ' ' }, +	{ TAINT_UNSIGNED_MODULE,	'E', ' ' },  };  /** @@ -228,12 +242,13 @@ static const struct tnt tnts[] = {   *  'C' - modules from drivers/staging are loaded.   *  'I' - Working around severe firmware bug.   *  'O' - Out-of-tree module has been loaded. + *  'E' - Unsigned module has been loaded.   *   *	The string is overwritten by the next call to print_tainted().   */  const char *print_tainted(void)  { -	static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ") + 1]; +	static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ")];  	if (tainted_mask) {  		char *s; @@ -274,8 +289,7 @@ unsigned long get_taint(void)  void add_taint(unsigned flag, enum lockdep_ok lockdep_ok)  {  	if (lockdep_ok == LOCKDEP_NOW_UNRELIABLE && __debug_locks_off()) -		printk(KERN_WARNING -		       "Disabling lock debugging due to kernel taint\n"); +		pr_warn("Disabling lock debugging due to kernel taint\n");  	set_bit(flag, &tainted_mask);  } @@ -380,8 +394,7 @@ late_initcall(init_oops_id);  void print_oops_end_marker(void)  {  	init_oops_id(); -	printk(KERN_WARNING "---[ end trace %016llx ]---\n", -		(unsigned long long)oops_id); +	pr_warn("---[ end trace %016llx ]---\n", (unsigned long long)oops_id);  }  /* @@ -459,7 +472,7 @@ EXPORT_SYMBOL(warn_slowpath_null);   * Called when gcc's -fstack-protector feature is used, and   * gcc detects corruption of the on-stack canary value   */ -void __stack_chk_fail(void) +__visible void __stack_chk_fail(void)  {  	panic("stack-protector: Kernel stack is corrupted in: %p\n",  		__builtin_return_address(0)); @@ -471,6 +484,13 @@ EXPORT_SYMBOL(__stack_chk_fail);  core_param(panic, panic_timeout, int, 0644);  core_param(pause_on_oops, pause_on_oops, int, 0644); +static int __init setup_crash_kexec_post_notifiers(char *s) +{ +	crash_kexec_post_notifiers = true; +	return 0; +} +early_param("crash_kexec_post_notifiers", setup_crash_kexec_post_notifiers); +  static int __init oops_setup(char *s)  {  	if (!s)  | 
