aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/dumpstack.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/dumpstack.c')
-rw-r--r--arch/x86/kernel/dumpstack.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 2d8a371d4339..c56bc2873030 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -109,6 +109,30 @@ print_context_stack(struct thread_info *tinfo,
109 } 109 }
110 return bp; 110 return bp;
111} 111}
112EXPORT_SYMBOL_GPL(print_context_stack);
113
114unsigned long
115print_context_stack_bp(struct thread_info *tinfo,
116 unsigned long *stack, unsigned long bp,
117 const struct stacktrace_ops *ops, void *data,
118 unsigned long *end, int *graph)
119{
120 struct stack_frame *frame = (struct stack_frame *)bp;
121 unsigned long *ret_addr = &frame->return_address;
122
123 while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
124 unsigned long addr = *ret_addr;
125
126 if (__kernel_text_address(addr)) {
127 ops->address(data, addr, 1);
128 frame = frame->next_frame;
129 ret_addr = &frame->return_address;
130 print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
131 }
132 }
133 return (unsigned long)frame;
134}
135EXPORT_SYMBOL_GPL(print_context_stack_bp);
112 136
113 137
114static void 138static void
@@ -141,10 +165,11 @@ static void print_trace_address(void *data, unsigned long addr, int reliable)
141} 165}
142 166
143static const struct stacktrace_ops print_trace_ops = { 167static const struct stacktrace_ops print_trace_ops = {
144 .warning = print_trace_warning, 168 .warning = print_trace_warning,
145 .warning_symbol = print_trace_warning_symbol, 169 .warning_symbol = print_trace_warning_symbol,
146 .stack = print_trace_stack, 170 .stack = print_trace_stack,
147 .address = print_trace_address, 171 .address = print_trace_address,
172 .walk_stack = print_context_stack,
148}; 173};
149 174
150void 175void
@@ -188,7 +213,7 @@ void dump_stack(void)
188} 213}
189EXPORT_SYMBOL(dump_stack); 214EXPORT_SYMBOL(dump_stack);
190 215
191static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; 216static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
192static int die_owner = -1; 217static int die_owner = -1;
193static unsigned int die_nest_count; 218static unsigned int die_nest_count;
194 219
@@ -207,11 +232,11 @@ unsigned __kprobes long oops_begin(void)
207 /* racy, but better than risking deadlock. */ 232 /* racy, but better than risking deadlock. */
208 raw_local_irq_save(flags); 233 raw_local_irq_save(flags);
209 cpu = smp_processor_id(); 234 cpu = smp_processor_id();
210 if (!__raw_spin_trylock(&die_lock)) { 235 if (!arch_spin_trylock(&die_lock)) {
211 if (cpu == die_owner) 236 if (cpu == die_owner)
212 /* nested oops. should stop eventually */; 237 /* nested oops. should stop eventually */;
213 else 238 else
214 __raw_spin_lock(&die_lock); 239 arch_spin_lock(&die_lock);
215 } 240 }
216 die_nest_c return } static int __devexit rdc321x_gpio_remove(struct platform_device *pdev) { int ret; struct rdc321x_gpio *rdc321x_gpio_dev = platform_get_drvdata(pdev); ret = gpiochip_remove(&rdc321x_gpio_dev->chip); if (ret) dev_err(&pdev->dev, "failed to unregister chip\n"); kfree(rdc321x_gpio_dev); platform_set_drvdata(pdev, NULL); return ret; } static struct platform_driver rdc321x_gpio_driver = { .driver.name = "rdc321x-gpio", .driver.owner = THIS_MODULE, .probe = rdc321x_gpio_probe, .remove = __devexit_p(rdc321x_gpio_remove), }; module_platform_driver(rdc321x_gpio_driver); MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); MODULE_DESCRIPTION("RDC321x GPIO driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:rdc321x-gpio"); oops_exit(); 261 oops_exit();
237 262
@@ -268,11 +293,12 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
268 293
269 show_registers(regs); 294 show_registers(regs);
270#ifdef CONFIG_X86_32 295#ifdef CONFIG_X86_32
271 sp = (unsigned long) (&regs->sp); 296 if (user_mode_vm(regs)) {
272 savesegment(ss, ss);
273 if (user_mode(regs)) {
274 sp = regs->sp; 297 sp = regs->sp;
275 ss = regs->ss & 0xffff; 298 ss = regs->ss & 0xffff;
299 } else {
300 sp = kernel_stack_pointer(regs);
301 savesegment(ss, ss);
276 } 302 }
277 printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); 303 printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
278 print_symbol("%s", regs->ip); 304 print_symbol("%s", regs->ip);