Blame view

kernel/panic.c 6.71 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
  /*
   *  linux/kernel/panic.c
   *
   *  Copyright (C) 1991, 1992  Linus Torvalds
   */
  
  /*
   * This function is used through-out the kernel (including mm and fs)
   * to indicate a major problem.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
16
17
18
19
  #include <linux/module.h>
  #include <linux/sched.h>
  #include <linux/delay.h>
  #include <linux/reboot.h>
  #include <linux/notifier.h>
  #include <linux/init.h>
  #include <linux/sysrq.h>
  #include <linux/interrupt.h>
  #include <linux/nmi.h>
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
20
  #include <linux/kexec.h>
657b3010d   Andrew Morton   [PATCH] panic.c b...
21
  #include <linux/debug_locks.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
  int panic_on_oops;
  int tainted;
dd287796d   Andrew Morton   [PATCH] pause_on_...
25
26
27
  static int pause_on_oops;
  static int pause_on_oops_flag;
  static DEFINE_SPINLOCK(pause_on_oops_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

dd287796d   Andrew Morton   [PATCH] pause_on_...
29
  int panic_timeout;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30

e041c6834   Alan Stern   [PATCH] Notifier ...
31
  ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  
  EXPORT_SYMBOL(panic_notifier_list);
  
  static int __init panic_setup(char *str)
  {
  	panic_timeout = simple_strtoul(str, NULL, 0);
  	return 1;
  }
  __setup("panic=", panic_setup);
  
  static long no_blink(long time)
  {
  	return 0;
  }
  
  /* Returns how long it waited in ms */
  long (*panic_blink)(long time);
  EXPORT_SYMBOL(panic_blink);
  
  /**
   *	panic - halt the system
   *	@fmt: The text string to print
   *
   *	Display a message, then perform cleanups.
   *
   *	This function never returns.
   */
   
  NORET_TYPE void panic(const char * fmt, ...)
  {
  	long i;
  	static char buf[1024];
  	va_list args;
347a8dc3b   Martin Schwidefsky   [PATCH] s390: cle...
65
  #if defined(CONFIG_S390)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
          unsigned long caller = (unsigned long) __builtin_return_address(0);
  #endif
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
68
69
70
71
72
73
  	/*
  	 * It's possible to come here directly from a panic-assertion and not
  	 * have preempt disabled. Some functions called from here want
  	 * preempt to be disabled. No point enabling it later though...
  	 */
  	preempt_disable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
77
78
79
80
  	bust_spinlocks(1);
  	va_start(args, fmt);
  	vsnprintf(buf, sizeof(buf), fmt, args);
  	va_end(args);
  	printk(KERN_EMERG "Kernel panic - not syncing: %s
  ",buf);
  	bust_spinlocks(0);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
81
82
83
84
85
  	/*
  	 * 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?
  	 */
6e274d144   Alexander Nyberg   [PATCH] kdump: Us...
86
  	crash_kexec(NULL);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
87

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  #ifdef CONFIG_SMP
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
89
90
91
92
93
  	/*
  	 * Note smp_send_stop is the usual smp shutdown function, which
  	 * unfortunately means it may not be hardened to work in a panic
  	 * situation.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
  	smp_send_stop();
  #endif
e041c6834   Alan Stern   [PATCH] Notifier ...
96
  	atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
  
  	if (!panic_blink)
  		panic_blink = no_blink;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
100
  	if (panic_timeout > 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
106
107
108
109
110
111
  		/*
  	 	 * 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);
  		for (i = 0; i < panic_timeout*1000; ) {
  			touch_nmi_watchdog();
  			i += panic_blink(i);
  			mdelay(1);
  			i++;
  		}
2f048ea81   Eric W. Biederman   [PATCH] Call emer...
112
113
114
  		/*	This will not be a clean reboot, with everything
  		 *	shutting down.  But if there is a chance of
  		 *	rebooting the system it will be rebooted.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
  		 */
2f048ea81   Eric W. Biederman   [PATCH] Call emer...
116
  		emergency_restart();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
120
  	}
  #ifdef __sparc__
  	{
  		extern int stop_a_enabled;
a271c241a   Tom 'spot' Callaway   [SPARC]: Stop-A p...
121
  		/* Make sure the user can actually press Stop-A (L1-A) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
  		stop_a_enabled = 1;
a271c241a   Tom 'spot' Callaway   [SPARC]: Stop-A p...
123
124
  		printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
  	}
  #endif
347a8dc3b   Martin Schwidefsky   [PATCH] s390: cle...
127
  #if defined(CONFIG_S390)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
131
          disabled_wait(caller);
  #endif
  	local_irq_enable();
  	for (i = 0;;) {
c22db9412   Jan Beulich   [PATCH] prevent r...
132
  		touch_softlockup_watchdog();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  		i += panic_blink(i);
  		mdelay(1);
  		i++;
  	}
  }
  
  EXPORT_SYMBOL(panic);
  
  /**
   *	print_tainted - return a string to represent the kernel taint state.
   *
   *  'P' - Proprietary module has been loaded.
   *  'F' - Module has been forcibly loaded.
   *  'S' - SMP with CPUs not designed for SMP.
   *  'R' - User forced a module unload.
   *  'M' - Machine had a machine check experience.
   *  'B' - System has hit bad_page.
34f5a3989   Theodore Ts'o   [PATCH] Add TAINT...
150
   *  'U' - Userspace-defined naughtiness.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
156
157
158
   *
   *	The string is overwritten by the next call to print_taint().
   */
   
  const char *print_tainted(void)
  {
  	static char buf[20];
  	if (tainted) {
bcdcd8e72   Pavel Emelianov   Report that kerne...
159
  		snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
164
  			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' : ' ',
34f5a3989   Theodore Ts'o   [PATCH] Add TAINT...
165
  			tainted & TAINT_BAD_PAGE ? 'B' : ' ',
bcdcd8e72   Pavel Emelianov   Report that kerne...
166
167
  			tainted & TAINT_USER ? 'U' : ' ',
  			tainted & TAINT_DIE ? 'D' : ' ');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
171
172
173
174
175
  	}
  	else
  		snprintf(buf, sizeof(buf), "Not tainted");
  	return(buf);
  }
  
  void add_taint(unsigned flag)
  {
068c4579f   Ingo Molnar   [PATCH] lockdep: ...
176
  	debug_locks = 0; /* can't trust the integrity of the kernel anymore */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
  	tainted |= flag;
  }
  EXPORT_SYMBOL(add_taint);
dd287796d   Andrew Morton   [PATCH] pause_on_...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  
  static int __init pause_on_oops_setup(char *str)
  {
  	pause_on_oops = simple_strtoul(str, NULL, 0);
  	return 1;
  }
  __setup("pause_on_oops=", pause_on_oops_setup);
  
  static void spin_msec(int msecs)
  {
  	int i;
  
  	for (i = 0; i < msecs; i++) {
  		touch_nmi_watchdog();
  		mdelay(1);
  	}
  }
  
  /*
   * It just happens that oops_enter() and oops_exit() are identically
   * implemented...
   */
  static void do_oops_enter_exit(void)
  {
  	unsigned long flags;
  	static int spin_counter;
  
  	if (!pause_on_oops)
  		return;
  
  	spin_lock_irqsave(&pause_on_oops_lock, flags);
  	if (pause_on_oops_flag == 0) {
  		/* This CPU may now print the oops message */
  		pause_on_oops_flag = 1;
  	} else {
  		/* We need to stall this CPU */
  		if (!spin_counter) {
  			/* This CPU gets to do the counting */
  			spin_counter = pause_on_oops;
  			do {
  				spin_unlock(&pause_on_oops_lock);
  				spin_msec(MSEC_PER_SEC);
  				spin_lock(&pause_on_oops_lock);
  			} while (--spin_counter);
  			pause_on_oops_flag = 0;
  		} else {
  			/* This CPU waits for a different one */
  			while (spin_counter) {
  				spin_unlock(&pause_on_oops_lock);
  				spin_msec(1);
  				spin_lock(&pause_on_oops_lock);
  			}
  		}
  	}
  	spin_unlock_irqrestore(&pause_on_oops_lock, flags);
  }
  
  /*
   * Return true if the calling CPU is allowed to print oops-related info.  This
   * is a bit racy..
   */
  int oops_may_print(void)
  {
  	return pause_on_oops_flag == 0;
  }
  
  /*
   * Called when the architecture enters its oops handler, before it prints
   * anything.  If this is the first CPU to oops, and it's oopsing the first time
   * then let it proceed.
   *
   * This is all enabled by the pause_on_oops kernel boot option.  We do all this
   * to ensure that oopses don't scroll off the screen.  It has the side-effect
   * of preventing later-oopsing CPUs from mucking up the display, too.
   *
   * It turns out that the CPU which is allowed to print ends up pausing for the
   * right duration, whereas all the other CPUs pause for twice as long: once in
   * oops_enter(), once in oops_exit().
   */
  void oops_enter(void)
  {
2c16e9c88   Arjan van de Ven   [PATCH] lockdep: ...
261
  	debug_locks_off(); /* can't trust the integrity of the kernel anymore */
dd287796d   Andrew Morton   [PATCH] pause_on_...
262
263
264
265
266
267
268
269
270
271
272
  	do_oops_enter_exit();
  }
  
  /*
   * Called when the architecture exits its oops handler, after printing
   * everything.
   */
  void oops_exit(void)
  {
  	do_oops_enter_exit();
  }
3162f751d   Arjan van de Ven   [PATCH] Add the _...
273
274
275
276
277
278
279
280
281
282
283
284
  
  #ifdef CONFIG_CC_STACKPROTECTOR
  /*
   * Called when gcc's -fstack-protector feature is used, and
   * gcc detects corruption of the on-stack canary value
   */
  void __stack_chk_fail(void)
  {
  	panic("stack-protector: Kernel stack is corrupted");
  }
  EXPORT_SYMBOL(__stack_chk_fail);
  #endif