• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/x86/kernel/
1/*
2 *  Copyright (C) 1991, 1992  Linus Torvalds
3 *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 */
5#include <linux/kallsyms.h>
6#include <linux/kprobes.h>
7#include <linux/uaccess.h>
8#include <linux/utsname.h>
9#include <linux/hardirq.h>
10#include <linux/kdebug.h>
11#include <linux/module.h>
12#include <linux/ptrace.h>
13#include <linux/ftrace.h>
14#include <linux/kexec.h>
15#include <linux/bug.h>
16#include <linux/nmi.h>
17#include <linux/sysfs.h>
18
19#include <asm/stacktrace.h>
20
21
22int panic_on_unrecovered_nmi;
23int panic_on_io_nmi;
24unsigned int code_bytes = 64;
25int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE;
26static int die_counter;
27
28void printk_address(unsigned long address, int reliable)
29{
30	printk(" [<%p>] %s%pS\n", (void *) address,
31			reliable ? "" : "? ", (void *) address);
32}
33
34#ifdef CONFIG_FUNCTION_GRAPH_TRACER
35static void
36print_ftrace_graph_addr(unsigned long addr, void *data,
37			const struct stacktrace_ops *ops,
38			struct thread_info *tinfo, int *graph)
39{
40	struct task_struct *task = tinfo->task;
41	unsigned long ret_addr;
42	int index = task->curr_ret_stack;
43
44	if (addr != (unsigned long)return_to_handler)
45		return;
46
47	if (!task->ret_stack || index < *graph)
48		return;
49
50	index -= *graph;
51	ret_addr = task->ret_stack[index].ret;
52
53	ops->address(data, ret_addr, 1);
54
55	(*graph)++;
56}
57#else
58static inline void
59print_ftrace_graph_addr(unsigned long addr, void *data,
60			const struct stacktrace_ops *ops,
61			struct thread_info *tinfo, int *graph)
62{ }
63#endif
64
65/*
66 * x86-64 can have up to three kernel stacks:
67 * process stack
68 * interrupt stack
69 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
70 */
71
72static inline int valid_stack_ptr(struct thread_info *tinfo,
73			void *p, unsigned int size, void *end)
74{
75	void *t = tinfo;
76	if (end) {
77		if (p < end && p >= (end-THREAD_SIZE))
78			return 1;
79		else
80			return 0;
81	}
82	return p > t && p < t + THREAD_SIZE - size;
83}
84
85unsigned long
86print_context_stack(struct thread_info *tinfo,
87		unsigned long *stack, unsigned long bp,
88		const struct stacktrace_ops *ops, void *data,
89		unsigned long *end, int *graph)
90{
91	struct stack_frame *frame = (struct stack_frame *)bp;
92
93	while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
94		unsigned long addr;
95
96		addr = *stack;
97		if (__kernel_text_address(addr)) {
98			if ((unsigned long) stack == bp + sizeof(long)) {
99				ops->address(data, addr, 1);
100				frame = frame->next_frame;
101				bp = (unsigned long) frame;
102			} else {
103				ops->address(data, addr, 0);
104			}
105			print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
106		}
107		stack++;
108	}
109	return bp;
110}
111EXPORT_SYMBOL_GPL(print_context_stack);
112
113unsigned long
114print_context_stack_bp(struct thread_info *tinfo,
115		       unsigned long *stack, unsigned long bp,
116		       const struct stacktrace_ops *ops, void *data,
117		       unsigned long *end, int *graph)
118{
119	struct stack_frame *frame = (struct stack_frame *)bp;
120	unsigned long *ret_addr = &frame->return_address;
121
122	while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
123		unsigned long addr = *ret_addr;
124
125		if (!__kernel_text_address(addr))
126			break;
127
128		ops->address(data, addr, 1);
129		frame = frame->next_frame;
130		ret_addr = &frame->return_address;
131		print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
132	}
133
134	return (unsigned long)frame;
135}
136EXPORT_SYMBOL_GPL(print_context_stack_bp);
137
138
139static void
140print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
141{
142	printk(data);
143	print_symbol(msg, symbol);
144	printk("\n");
145}
146
147static void print_trace_warning(void *data, char *msg)
148{
149	printk("%s%s\n", (char *)data, msg);
150}
151
152static int print_trace_stack(void *data, char *name)
153{
154	printk("%s <%s> ", (char *)data, name);
155	return 0;
156}
157
158/*
159 * Print one address/symbol entries per line.
160 */
161static void print_trace_address(void *data, unsigned long addr, int reliable)
162{
163	touch_nmi_watchdog();
164	printk(data);
165	printk_address(addr, reliable);
166}
167
168static const struct stacktrace_ops print_trace_ops = {
169	.warning		= print_trace_warning,
170	.warning_symbol		= print_trace_warning_symbol,
171	.stack			= print_trace_stack,
172	.address		= print_trace_address,
173	.walk_stack		= print_context_stack,
174};
175
176void
177show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
178		unsigned long *stack, unsigned long bp, char *log_lvl)
179{
180	printk("%sCall Trace:\n", log_lvl);
181	dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
182}
183
184void show_trace(struct task_struct *task, struct pt_regs *regs,
185		unsigned long *stack, unsigned long bp)
186{
187	show_trace_log_lvl(task, regs, stack, bp, "");
188}
189
190void show_stack(struct task_struct *task, unsigned long *sp)
191{
192	show_stack_log_lvl(task, NULL, sp, 0, "");
193}
194
195/*
196 * The architecture-independent dump_stack generator
197 */
198void dump_stack(void)
199{
200	unsigned long bp = 0;
201	unsigned long stack;
202
203#ifdef CONFIG_FRAME_POINTER
204	if (!bp)
205		get_bp(bp);
206#endif
207
208	printk("Pid: %d, comm: %.20s %s %s %.*s\n",
209		current->pid, current->comm, print_tainted(),
210		init_utsname()->release,
211		(int)strcspn(init_utsname()->version, " "),
212		init_utsname()->version);
213	show_trace(NULL, NULL, &stack, bp);
214}
215EXPORT_SYMBOL(dump_stack);
216
217static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
218static int die_owner = -1;
219static unsigned int die_nest_count;
220
221unsigned __kprobes long oops_begin(void)
222{
223	int cpu;
224	unsigned long flags;
225
226	oops_enter();
227
228	/* racy, but better than risking deadlock. */
229	raw_local_irq_save(flags);
230	cpu = smp_processor_id();
231	if (!arch_spin_trylock(&die_lock)) {
232		if (cpu == die_owner)
233			/* nested oops. should stop eventually */;
234		else
235			arch_spin_lock(&die_lock);
236	}
237	die_nest_count++;
238	die_owner = cpu;
239	console_verbose();
240	bust_spinlocks(1);
241	return flags;
242}
243
244void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
245{
246	if (regs && kexec_should_crash(current))
247		crash_kexec(regs);
248
249	bust_spinlocks(0);
250	die_owner = -1;
251	add_taint(TAINT_DIE);
252	die_nest_count--;
253	if (!die_nest_count)
254		/* Nest count reaches zero, release the lock. */
255		arch_spin_unlock(&die_lock);
256	raw_local_irq_restore(flags);
257	oops_exit();
258
259	if (!signr)
260		return;
261	if (in_interrupt())
262		panic("Fatal exception in interrupt");
263	if (panic_on_oops)
264		panic("Fatal exception");
265	do_exit(signr);
266}
267
268int __kprobes __die(const char *str, struct pt_regs *regs, long err)
269{
270#ifdef CONFIG_X86_32
271	unsigned short ss;
272	unsigned long sp;
273#endif
274	printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
275#ifdef CONFIG_PREEMPT
276	printk("PREEMPT ");
277#endif
278#ifdef CONFIG_SMP
279	printk("SMP ");
280#endif
281#ifdef CONFIG_DEBUG_PAGEALLOC
282	printk("DEBUG_PAGEALLOC");
283#endif
284	printk("\n");
285	sysfs_printk_last_file();
286	if (notify_die(DIE_OOPS, str, regs, err,
287			current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
288		return 1;
289
290	show_registers(regs);
291#ifdef CONFIG_X86_32
292	if (user_mode_vm(regs)) {
293		sp = regs->sp;
294		ss = regs->ss & 0xffff;
295	} else {
296		sp = kernel_stack_pointer(regs);
297		savesegment(ss, ss);
298	}
299	printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
300	print_symbol("%s", regs->ip);
301	printk(" SS:ESP %04x:%08lx\n", ss, sp);
302#else
303	/* Executive summary in case the oops scrolled away */
304	printk(KERN_ALERT "RIP ");
305	printk_address(regs->ip, 1);
306	printk(" RSP <%016lx>\n", regs->sp);
307#endif
308	return 0;
309}
310
311/*
312 * This is gone through when something in the kernel has done something bad
313 * and is about to be terminated:
314 */
315void die(const char *str, struct pt_regs *regs, long err)
316{
317	unsigned long flags = oops_begin();
318	int sig = SIGSEGV;
319
320	if (!user_mode_vm(regs))
321		report_bug(regs->ip, regs);
322
323	if (__die(str, regs, err))
324		sig = 0;
325	oops_end(flags, regs, sig);
326}
327
328void notrace __kprobes
329die_nmi(char *str, struct pt_regs *regs, int do_panic)
330{
331	unsigned long flags;
332
333	if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP)
334		return;
335
336	/*
337	 * We are in trouble anyway, lets at least try
338	 * to get a message out.
339	 */
340	flags = oops_begin();
341	printk(KERN_EMERG "%s", str);
342	printk(" on CPU%d, ip %08lx, registers:\n",
343		smp_processor_id(), regs->ip);
344	show_registers(regs);
345	oops_end(flags, regs, 0);
346	if (do_panic || panic_on_oops)
347		panic("Non maskable interrupt");
348	nmi_exit();
349	local_irq_enable();
350	do_exit(SIGBUS);
351}
352
353static int __init oops_setup(char *s)
354{
355	if (!s)
356		return -EINVAL;
357	if (!strcmp(s, "panic"))
358		panic_on_oops = 1;
359	return 0;
360}
361early_param("oops", oops_setup);
362
363static int __init kstack_setup(char *s)
364{
365	if (!s)
366		return -EINVAL;
367	kstack_depth_to_print = simple_strtoul(s, NULL, 0);
368	return 0;
369}
370early_param("kstack", kstack_setup);
371
372static int __init code_bytes_setup(char *s)
373{
374	code_bytes = simple_strtoul(s, NULL, 0);
375	if (code_bytes > 8192)
376		code_bytes = 8192;
377
378	return 1;
379}
380__setup("code_bytes=", code_bytes_setup);
381