11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/kernel/panic.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds 51da177e4SLinus Torvalds */ 61da177e4SLinus Torvalds 71da177e4SLinus Torvalds /* 81da177e4SLinus Torvalds * This function is used through-out the kernel (including mm and fs) 91da177e4SLinus Torvalds * to indicate a major problem. 101da177e4SLinus Torvalds */ 111da177e4SLinus Torvalds #include <linux/config.h> 121da177e4SLinus Torvalds #include <linux/module.h> 131da177e4SLinus Torvalds #include <linux/sched.h> 141da177e4SLinus Torvalds #include <linux/delay.h> 151da177e4SLinus Torvalds #include <linux/reboot.h> 161da177e4SLinus Torvalds #include <linux/notifier.h> 171da177e4SLinus Torvalds #include <linux/init.h> 181da177e4SLinus Torvalds #include <linux/sysrq.h> 191da177e4SLinus Torvalds #include <linux/interrupt.h> 201da177e4SLinus Torvalds #include <linux/nmi.h> 21dc009d92SEric W. Biederman #include <linux/kexec.h> 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds int panic_timeout; 241da177e4SLinus Torvalds int panic_on_oops; 251da177e4SLinus Torvalds int tainted; 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds EXPORT_SYMBOL(panic_timeout); 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds struct notifier_block *panic_notifier_list; 301da177e4SLinus Torvalds 311da177e4SLinus Torvalds EXPORT_SYMBOL(panic_notifier_list); 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds static int __init panic_setup(char *str) 341da177e4SLinus Torvalds { 351da177e4SLinus Torvalds panic_timeout = simple_strtoul(str, NULL, 0); 361da177e4SLinus Torvalds return 1; 371da177e4SLinus Torvalds } 381da177e4SLinus Torvalds __setup("panic=", panic_setup); 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds static long no_blink(long time) 411da177e4SLinus Torvalds { 421da177e4SLinus Torvalds return 0; 431da177e4SLinus Torvalds } 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds /* Returns how long it waited in ms */ 461da177e4SLinus Torvalds long (*panic_blink)(long time); 471da177e4SLinus Torvalds EXPORT_SYMBOL(panic_blink); 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds /** 501da177e4SLinus Torvalds * panic - halt the system 511da177e4SLinus Torvalds * @fmt: The text string to print 521da177e4SLinus Torvalds * 531da177e4SLinus Torvalds * Display a message, then perform cleanups. 541da177e4SLinus Torvalds * 551da177e4SLinus Torvalds * This function never returns. 561da177e4SLinus Torvalds */ 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds NORET_TYPE void panic(const char * fmt, ...) 591da177e4SLinus Torvalds { 601da177e4SLinus Torvalds long i; 611da177e4SLinus Torvalds static char buf[1024]; 621da177e4SLinus Torvalds va_list args; 631da177e4SLinus Torvalds #if defined(CONFIG_ARCH_S390) 641da177e4SLinus Torvalds unsigned long caller = (unsigned long) __builtin_return_address(0); 651da177e4SLinus Torvalds #endif 661da177e4SLinus Torvalds 67dc009d92SEric W. Biederman /* 68dc009d92SEric W. Biederman * It's possible to come here directly from a panic-assertion and not 69dc009d92SEric W. Biederman * have preempt disabled. Some functions called from here want 70dc009d92SEric W. Biederman * preempt to be disabled. No point enabling it later though... 71dc009d92SEric W. Biederman */ 72dc009d92SEric W. Biederman preempt_disable(); 73dc009d92SEric W. Biederman 741da177e4SLinus Torvalds bust_spinlocks(1); 751da177e4SLinus Torvalds va_start(args, fmt); 761da177e4SLinus Torvalds vsnprintf(buf, sizeof(buf), fmt, args); 771da177e4SLinus Torvalds va_end(args); 781da177e4SLinus Torvalds printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); 791da177e4SLinus Torvalds bust_spinlocks(0); 801da177e4SLinus Torvalds 81dc009d92SEric W. Biederman /* 82dc009d92SEric W. Biederman * If we have crashed and we have a crash kernel loaded let it handle 83dc009d92SEric W. Biederman * everything else. 84dc009d92SEric W. Biederman * Do we want to call this before we try to display a message? 85dc009d92SEric W. Biederman */ 866e274d14SAlexander Nyberg crash_kexec(NULL); 87dc009d92SEric W. Biederman 881da177e4SLinus Torvalds #ifdef CONFIG_SMP 89dc009d92SEric W. Biederman /* 90dc009d92SEric W. Biederman * Note smp_send_stop is the usual smp shutdown function, which 91dc009d92SEric W. Biederman * unfortunately means it may not be hardened to work in a panic 92dc009d92SEric W. Biederman * situation. 93dc009d92SEric W. Biederman */ 941da177e4SLinus Torvalds smp_send_stop(); 951da177e4SLinus Torvalds #endif 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds notifier_call_chain(&panic_notifier_list, 0, buf); 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds if (!panic_blink) 1001da177e4SLinus Torvalds panic_blink = no_blink; 1011da177e4SLinus Torvalds 102dc009d92SEric W. Biederman if (panic_timeout > 0) { 1031da177e4SLinus Torvalds /* 1041da177e4SLinus Torvalds * Delay timeout seconds before rebooting the machine. 1051da177e4SLinus Torvalds * We can't use the "normal" timers since we just panicked.. 1061da177e4SLinus Torvalds */ 1071da177e4SLinus Torvalds printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); 1081da177e4SLinus Torvalds for (i = 0; i < panic_timeout*1000; ) { 1091da177e4SLinus Torvalds touch_nmi_watchdog(); 1101da177e4SLinus Torvalds i += panic_blink(i); 1111da177e4SLinus Torvalds mdelay(1); 1121da177e4SLinus Torvalds i++; 1131da177e4SLinus Torvalds } 114*2f048ea8SEric W. Biederman /* This will not be a clean reboot, with everything 115*2f048ea8SEric W. Biederman * shutting down. But if there is a chance of 116*2f048ea8SEric W. Biederman * rebooting the system it will be rebooted. 1171da177e4SLinus Torvalds */ 118*2f048ea8SEric W. Biederman emergency_restart(); 1191da177e4SLinus Torvalds } 1201da177e4SLinus Torvalds #ifdef __sparc__ 1211da177e4SLinus Torvalds { 1221da177e4SLinus Torvalds extern int stop_a_enabled; 123a271c241STom 'spot' Callaway /* Make sure the user can actually press Stop-A (L1-A) */ 1241da177e4SLinus Torvalds stop_a_enabled = 1; 125a271c241STom 'spot' Callaway printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n"); 1261da177e4SLinus Torvalds } 1271da177e4SLinus Torvalds #endif 1281da177e4SLinus Torvalds #if defined(CONFIG_ARCH_S390) 1291da177e4SLinus Torvalds disabled_wait(caller); 1301da177e4SLinus Torvalds #endif 1311da177e4SLinus Torvalds local_irq_enable(); 1321da177e4SLinus Torvalds for (i = 0;;) { 1331da177e4SLinus Torvalds i += panic_blink(i); 1341da177e4SLinus Torvalds mdelay(1); 1351da177e4SLinus Torvalds i++; 1361da177e4SLinus Torvalds } 1371da177e4SLinus Torvalds } 1381da177e4SLinus Torvalds 1391da177e4SLinus Torvalds EXPORT_SYMBOL(panic); 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds /** 1421da177e4SLinus Torvalds * print_tainted - return a string to represent the kernel taint state. 1431da177e4SLinus Torvalds * 1441da177e4SLinus Torvalds * 'P' - Proprietary module has been loaded. 1451da177e4SLinus Torvalds * 'F' - Module has been forcibly loaded. 1461da177e4SLinus Torvalds * 'S' - SMP with CPUs not designed for SMP. 1471da177e4SLinus Torvalds * 'R' - User forced a module unload. 1481da177e4SLinus Torvalds * 'M' - Machine had a machine check experience. 1491da177e4SLinus Torvalds * 'B' - System has hit bad_page. 1501da177e4SLinus Torvalds * 1511da177e4SLinus Torvalds * The string is overwritten by the next call to print_taint(). 1521da177e4SLinus Torvalds */ 1531da177e4SLinus Torvalds 1541da177e4SLinus Torvalds const char *print_tainted(void) 1551da177e4SLinus Torvalds { 1561da177e4SLinus Torvalds static char buf[20]; 1571da177e4SLinus Torvalds if (tainted) { 1581da177e4SLinus Torvalds snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c", 1591da177e4SLinus Torvalds tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', 1601da177e4SLinus Torvalds tainted & TAINT_FORCED_MODULE ? 'F' : ' ', 1611da177e4SLinus Torvalds tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', 1621da177e4SLinus Torvalds tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', 1631da177e4SLinus Torvalds tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', 1641da177e4SLinus Torvalds tainted & TAINT_BAD_PAGE ? 'B' : ' '); 1651da177e4SLinus Torvalds } 1661da177e4SLinus Torvalds else 1671da177e4SLinus Torvalds snprintf(buf, sizeof(buf), "Not tainted"); 1681da177e4SLinus Torvalds return(buf); 1691da177e4SLinus Torvalds } 1701da177e4SLinus Torvalds 1711da177e4SLinus Torvalds void add_taint(unsigned flag) 1721da177e4SLinus Torvalds { 1731da177e4SLinus Torvalds tainted |= flag; 1741da177e4SLinus Torvalds } 1751da177e4SLinus Torvalds EXPORT_SYMBOL(add_taint); 176