diff options
Diffstat (limited to 'arch/x86/kernel/dumpstack.c')
| -rw-r--r-- | arch/x86/kernel/dumpstack.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index b8ce165dde5d..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 | } |
| 112 | EXPORT_SYMBOL_GPL(print_context_stack); | ||
| 113 | |||
| 114 | unsigned long | ||
| 115 | print_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 | } | ||
| 135 | EXPORT_SYMBOL_GPL(print_context_stack_bp); | ||
| 112 | 136 | ||
| 113 | 137 | ||
| 114 | static void | 138 | static void |
| @@ -141,10 +165,11 @@ static void print_trace_address(void *data, unsigned long addr, int reliable) | |||
| 141 | } | 165 | } |
| 142 | 166 | ||
| 143 | static const struct stacktrace_ops print_trace_ops = { | 167 | static 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 | ||
| 150 | void | 175 | void |
| @@ -188,7 +213,7 @@ void dump_stack(void) | |||
| 188 | } | 213 | } |
| 189 | EXPORT_SYMBOL(dump_stack); | 214 | EXPORT_SYMBOL(dump_stack); |
| 190 | 215 | ||
| 191 | static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; | 216 | static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; |
| 192 | static int die_owner = -1; | 217 | static int die_owner = -1; |
| 193 | static unsigned int die_nest_count; | 218 | static 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_count++; | 241 | die_nest_count++; |
| 217 | die_owner = cpu; | 242 | die_owner = cpu; |
| @@ -231,7 +256,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) | |||
| 231 | die_nest_count--; | 256 | die_nest_count--; |
| 232 | if (!die_nest_count) | 257 | if (!die_nest_count) |
| 233 | /* Nest count reaches zero, release the lock. */ | 258 | /* Nest count reaches zero, release the lock. */ |
| 234 | __raw_spin_unlock(&die_lock); | 259 | arch_spin_unlock(&die_lock); |
| 235 | raw_local_irq_restore(flags); | 260 | raw_local_irq_restore(flags); |
| 236 | oops_exit(); | 261 | oops_exit(); |
| 237 | 262 | ||
