diff options
author | Josh Poimboeuf <jpoimboe@redhat.com> | 2016-08-24 12:50:17 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-09-08 02:58:40 -0400 |
commit | 4b8afafbe743be1a81c96ddcd75b19c534d5e262 (patch) | |
tree | b54d1bae9c6aac036566ff9c6bb330812aad810a /arch/x86/kernel | |
parent | d438f5fda30ec087512355e405e9c8955d8bd337 (diff) |
x86/dumpstack: Add get_stack_pointer() and get_frame_pointer()
The various functions involved in dumping the stack all do similar
things with regard to getting the stack pointer and the frame pointer
based on the regs and task arguments. Create helper functions to
do that instead.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: Andy Lutomirski <luto@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Byungchul Park <byungchul.park@lge.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/f448914885a35f333fe04da1b97a6c2cc1f80974.1472057064.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/dumpstack.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack_32.c | 25 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack_64.c | 30 |
3 files changed, 10 insertions, 50 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index f0ddf855957e..6d6f46837eea 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -170,15 +170,14 @@ show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
170 | void show_stack(struct task_struct *task, unsigned long *sp) | 170 | void show_stack(struct task_struct *task, unsigned long *sp) |
171 | { | 171 | { |
172 | unsigned long bp = 0; | 172 | unsigned long bp = 0; |
173 | unsigned long stack; | ||
174 | 173 | ||
175 | /* | 174 | /* |
176 | * Stack frames below this one aren't interesting. Don't show them | 175 | * Stack frames below this one aren't interesting. Don't show them |
177 | * if we're printing for %current. | 176 | * if we're printing for %current. |
178 | */ | 177 | */ |
179 | if (!sp && (!task || task == current)) { | 178 | if (!sp && (!task || task == current)) { |
180 | sp = &stack; | 179 | sp = get_stack_pointer(current, NULL); |
181 | bp = stack_frame(current, NULL); | 180 | bp = (unsigned long)get_frame_pointer(current, NULL); |
182 | } | 181 | } |
183 | 182 | ||
184 | show_stack_log_lvl(task, NULL, sp, bp, ""); | 183 | show_stack_log_lvl(task, NULL, sp, bp, ""); |
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 09675712eba8..358fe1cd4e5b 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -46,19 +46,9 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
46 | int graph = 0; | 46 | int graph = 0; |
47 | u32 *prev_esp; | 47 | u32 *prev_esp; |
48 | 48 | ||
49 | if (!task) | 49 | task = task ? : current; |
50 | task = current; | 50 | stack = stack ? : get_stack_pointer(task, regs); |
51 | 51 | bp = bp ? : (unsigned long)get_frame_pointer(task, regs); | |
52 | if (!stack) { | ||
53 | unsigned long dummy; | ||
54 | |||
55 | stack = &dummy; | ||
56 | if (task != current) | ||
57 | stack = (unsigned long *)task->thread.sp; | ||
58 | } | ||
59 | |||
60 | if (!bp) | ||
61 | bp = stack_frame(task, regs); | ||
62 | 52 | ||
63 | for (;;) { | 53 | for (;;) { |
64 | void *end_stack; | 54 | void *end_stack; |
@@ -95,14 +85,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
95 | unsigned long *stack; | 85 | unsigned long *stack; |
96 | int i; | 86 | int i; |
97 | 87 | ||
98 | if (sp == NULL) { | 88 | sp = sp ? : get_stack_pointer(task, regs); |
99 | if (regs) | ||
100 | sp = (unsigned long *)regs->sp; | ||
101 | else if (task) | ||
102 | sp = (unsigned long *)task->thread.sp; | ||
103 | else | ||
104 | sp = (unsigned long *)&sp; | ||
105 | } | ||
106 | 89 | ||
107 | stack = sp; | 90 | stack = sp; |
108 | for (i = 0; i < kstack_depth_to_print; i++) { | 91 | for (i = 0; i < kstack_depth_to_print; i++) { |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 066eb5c77fd6..7f3b8066f719 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -151,25 +151,14 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
151 | { | 151 | { |
152 | const unsigned cpu = get_cpu(); | 152 | const unsigned cpu = get_cpu(); |
153 | unsigned long *irq_stack = (unsigned long *)per_cpu(irq_stack_ptr, cpu); | 153 | unsigned long *irq_stack = (unsigned long *)per_cpu(irq_stack_ptr, cpu); |
154 | unsigned long dummy; | ||
155 | unsigned used = 0; | 154 | unsigned used = 0; |
156 | int graph = 0; | 155 | int graph = 0; |
157 | int done = 0; | 156 | int done = 0; |
158 | 157 | ||
159 | if (!task) | 158 | task = task ? : current; |
160 | task = current; | 159 | stack = stack ? : get_stack_pointer(task, regs); |
160 | bp = bp ? : (unsigned long)get_frame_pointer(task, regs); | ||
161 | 161 | ||
162 | if (!stack) { | ||
163 | if (regs) | ||
164 | stack = (unsigned long *)regs->sp; | ||
165 | else if (task != current) | ||
166 | stack = (unsigned long *)task->thread.sp; | ||
167 | else | ||
168 | stack = &dummy; | ||
169 | } | ||
170 | |||
171 | if (!bp) | ||
172 | bp = stack_frame(task, regs); | ||
173 | /* | 162 | /* |
174 | * Print function call entries in all stacks, starting at the | 163 | * Print function call entries in all stacks, starting at the |
175 | * current stack address. If the stacks consist of nested | 164 | * current stack address. If the stacks consist of nested |
@@ -256,18 +245,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
256 | irq_stack_end = (unsigned long *)(per_cpu(irq_stack_ptr, cpu)); | 245 | irq_stack_end = (unsigned long *)(per_cpu(irq_stack_ptr, cpu)); |
257 | irq_stack = irq_stack_end - (IRQ_STACK_SIZE / sizeof(long)); | 246 | irq_stack = irq_stack_end - (IRQ_STACK_SIZE / sizeof(long)); |
258 | 247 | ||
259 | /* | 248 | sp = sp ? : get_stack_pointer(task, regs); |
260 | * Debugging aid: "show_stack(NULL, NULL);" prints the | ||
261 | * back trace for this cpu: | ||
262 | */ | ||
263 | if (sp == NULL) { | ||
264 | if (regs) | ||
265 | sp = (unsigned long *)regs->sp; | ||
266 | else if (task) | ||
267 | sp = (unsigned long *)task->thread.sp; | ||
268 | else | ||
269 | sp = (unsigned long *)&sp; | ||
270 | } | ||
271 | 249 | ||
272 | stack = sp; | 250 | stack = sp; |
273 | for (i = 0; i < kstack_depth_to_print; i++) { | 251 | for (i = 0; i < kstack_depth_to_print; i++) { |