diff options
Diffstat (limited to 'arch/microblaze/kernel/traps.c')
-rw-r--r-- | arch/microblaze/kernel/traps.c | 91 |
1 files changed, 40 insertions, 51 deletions
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c index 75e49202a5ed..ba034d421ec2 100644 --- a/arch/microblaze/kernel/traps.c +++ b/arch/microblaze/kernel/traps.c | |||
@@ -16,13 +16,14 @@ | |||
16 | 16 | ||
17 | #include <asm/exceptions.h> | 17 | #include <asm/exceptions.h> |
18 | #include <asm/system.h> | 18 | #include <asm/system.h> |
19 | #include <asm/unwind.h> | ||
19 | 20 | ||
20 | void trap_init(void) | 21 | void trap_init(void) |
21 | { | 22 | { |
22 | __enable_hw_exceptions(); | 23 | __enable_hw_exceptions(); |
23 | } | 24 | } |
24 | 25 | ||
25 | static unsigned long kstack_depth_to_print = 24; | 26 | static unsigned long kstack_depth_to_print; /* 0 == entire stack */ |
26 | 27 | ||
27 | static int __init kstack_setup(char *s) | 28 | static int __init kstack_setup(char *s) |
28 | { | 29 | { |
@@ -30,31 +31,47 @@ static int __init kstack_setup(char *s) | |||
30 | } | 31 | } |
31 | __setup("kstack=", kstack_setup); | 32 | __setup("kstack=", kstack_setup); |
32 | 33 | ||
33 | void show_trace(struct task_struct *task, unsigned long *stack) | 34 | void show_stack(struct task_struct *task, unsigned long *sp) |
34 | { | 35 | { |
35 | unsigned long addr; | 36 | unsigned long words_to_show; |
36 | 37 | u32 fp = (u32) sp; | |
37 | if (!stack) | 38 | |
38 | stack = (unsigned long *)&stack; | 39 | if (fp == 0) { |
40 | if (task) { | ||
41 | fp = ((struct thread_info *) | ||
42 | (task->stack))->cpu_context.r1; | ||
43 | } else { | ||
44 | /* Pick up caller of dump_stack() */ | ||
45 | fp = (u32)&sp - 8; | ||
46 | } | ||
47 | } | ||
39 | 48 | ||
40 | printk(KERN_NOTICE "Call Trace: "); | 49 | words_to_show = (THREAD_SIZE - (fp & (THREAD_SIZE - 1))) >> 2; |
41 | #ifdef CONFIG_KALLSYMS | 50 | if (kstack_depth_to_print && (words_to_show > kstack_depth_to_print)) |
42 | printk(KERN_NOTICE "\n"); | 51 | words_to_show = kstack_depth_to_print; |
43 | #endif | 52 | |
44 | while (!kstack_end(stack)) { | 53 | pr_info("Kernel Stack:\n"); |
45 | addr = *stack++; | 54 | |
46 | /* | 55 | /* |
47 | * If the address is either in the text segment of the | 56 | * Make the first line an 'odd' size if necessary to get |
48 | * kernel, or in the region which contains vmalloc'ed | 57 | * remaining lines to start at an address multiple of 0x10 |
49 | * memory, it *may* be the address of a calling | 58 | */ |
50 | * routine; if so, print it so that someone tracing | 59 | if (fp & 0xF) { |
51 | * down the cause of the crash will be able to figure | 60 | unsigned long line1_words = (0x10 - (fp & 0xF)) >> 2; |
52 | * out the call path that was taken. | 61 | if (line1_words < words_to_show) { |
53 | */ | 62 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, |
54 | if (kernel_text_address(addr)) | 63 | 4, (void *)fp, line1_words << 2, 0); |
55 | print_ip_sym(addr); | 64 | fp += line1_words << 2; |
65 | words_to_show -= line1_words; | ||
66 | } | ||
56 | } | 67 | } |
57 | printk(KERN_NOTICE "\n"); | 68 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, (void *)fp, |
69 | words_to_show << 2, 0); | ||
70 | printk(KERN_INFO "\n\n"); | ||
71 | |||
72 | pr_info("Call Trace:\n"); | ||
73 | microblaze_unwind(task, NULL); | ||
74 | pr_info("\n"); | ||
58 | 75 | ||
59 | if (!task) | 76 | if (!task) |
60 | task = current; | 77 | task = current; |
@@ -62,34 +79,6 @@ void show_trace(struct task_struct *task, unsigned long *stack) | |||
62 | debug_show_held_locks(task); | 79 | debug_show_held_locks(task); |
63 | } | 80 | } |
64 | 81 | ||
65 | void show_stack(struct task_struct *task, unsigned long *sp) | ||
66 | { | ||
67 | unsigned long *stack; | ||
68 | int i; | ||
69 | |||
70 | if (sp == NULL) { | ||
71 | if (task) | ||
72 | sp = (unsigned long *) ((struct thread_info *) | ||
73 | (task->stack))->cpu_context.r1; | ||
74 | else | ||
75 | sp = (unsigned long *)&sp; | ||
76 | } | ||
77 | |||
78 | stack = sp; | ||
79 | |||
80 | printk(KERN_INFO "\nStack:\n "); | ||
81 | |||
82 | for (i = 0; i < kstack_depth_to_print; i++) { | ||
83 | if (kstack_end(sp)) | ||
84 | break; | ||
85 | if (i && ((i % 8) == 0)) | ||
86 | printk("\n "); | ||
87 | printk("%08lx ", *sp++); | ||
88 | } | ||
89 | printk("\n"); | ||
90 | show_trace(task, stack); | ||
91 | } | ||
92 | |||
93 | void dump_stack(void) | 82 | void dump_stack(void) |
94 | { | 83 | { |
95 | show_stack(NULL, NULL); | 84 | show_stack(NULL, NULL); |