1
2
3
4
5
6
7
8
9
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/delay.h>
15#include <linux/reboot.h>
16#include <linux/notifier.h>
17#include <linux/init.h>
18#include <linux/sysrq.h>
19#include <linux/syscalls.h>
20#include <linux/interrupt.h>
21#include <linux/nmi.h>
22
23int panic_timeout;
24int panic_on_oops = 1;
25int panic_on_unrecovered_nmi;
26int tainted;
27int halt_on_dump_err = 0;
28
29EXPORT_SYMBOL(panic_timeout);
30EXPORT_SYMBOL_GPL(halt_on_dump_err);
31
32struct notifier_block *panic_notifier_list;
33
34EXPORT_SYMBOL(panic_notifier_list);
35
36static int __init panic_setup(char *str)
37{
38 panic_timeout = simple_strtoul(str, NULL, 0);
39 return 1;
40}
41__setup("panic=", panic_setup);
42
43static long no_blink(long time)
44{
45 return 0;
46}
47
48
49long (*panic_blink)(long time) = no_blink;
50EXPORT_SYMBOL(panic_blink);
51
52
53
54
55
56
57
58
59
60
61
62NORET_TYPE void panic(const char * fmt, ...)
63{
64 long i;
65 static char buf[1024];
66 va_list args;
67#if defined(CONFIG_ARCH_S390)
68 unsigned long caller = (unsigned long) __builtin_return_address(0);
69#endif
70
71 bust_spinlocks(1);
72 va_start(args, fmt);
73 vsnprintf(buf, sizeof(buf), fmt, args);
74 va_end(args);
75 printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
76 if (crashdump_func())
77 BUG();
78 bust_spinlocks(0);
79
80#ifdef CONFIG_SMP
81 if (!crashdump_mode())
82 smp_send_stop();
83#endif
84
85 notifier_call_chain(&panic_notifier_list, 0, buf);
86
87 if (panic_timeout > 0 && !halt_on_dump_err)
88 {
89
90
91
92
93 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
94 for (i = 0; i < panic_timeout*1000; ) {
95 touch_nmi_watchdog();
96 i += panic_blink(i);
97 mdelay(1);
98 i++;
99 }
100
101
102
103
104
105 machine_restart(NULL);
106 }
107#ifdef __sparc__
108 {
109 extern int stop_a_enabled;
110
111 stop_a_enabled = 1;
112 printk(KERN_EMERG "Press L1-A to return to the boot prom\n");
113 }
114#endif
115#if defined(CONFIG_ARCH_S390)
116 disabled_wait(caller);
117#endif
118 local_irq_enable();
119 for (i = 0;;) {
120 i += panic_blink(i);
121 mdelay(1);
122 i++;
123 }
124}
125
126EXPORT_SYMBOL(panic);
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141const char *print_tainted(void)
142{
143 static char buf[20];
144 if (tainted) {
145 snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c",
146 tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
147 tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
148 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
149 tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
150 tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
151 tainted & TAINT_BAD_PAGE ? 'B' : ' ');
152 }
153 else
154 snprintf(buf, sizeof(buf), "Not tainted");
155 return(buf);
156}
157
158void add_taint(unsigned flag)
159{
160 tainted |= flag;
161}
162EXPORT_SYMBOL(add_taint);
163