Mostly cosmetic changes:

- Group common stack pointer code at the top
- Simplify the first frame logic
- Code stackframe iteration into for...loop construct
- Check for trace->nr_entries overflow before adding any into the array

Suggested-by: Nicolai Stange <nsta...@suse.de>
Signed-off-by: Joe Lawrence <joe.lawre...@redhat.com>
---
 arch/powerpc/kernel/stacktrace.c | 40 +++++++++++---------------------
 1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index 06688f4d557b..28c3c25755d7 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -95,20 +95,11 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk,
                                struct stack_trace *trace)
 {
        unsigned long sp;
+       unsigned long newsp;
        unsigned long stack_page = (unsigned long)task_stack_page(tsk);
        unsigned long stack_end;
        int graph_idx = 0;
-
-       /*
-        * The last frame (unwinding first) may not yet have saved
-        * its LR onto the stack.
-        */
-       int firstframe = 1;
-
-       if (tsk == current)
-               sp = current_stack_pointer();
-       else
-               sp = tsk->thread.ksp;
+       bool firstframe;
 
        stack_end = stack_page + THREAD_SIZE;
        if (!is_idle_task(tsk)) {
@@ -135,14 +126,20 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk,
                stack_end -= STACK_FRAME_OVERHEAD;
        }
 
+       if (tsk == current)
+               sp = current_stack_pointer();
+       else
+               sp = tsk->thread.ksp;
+
        if (sp < stack_page + sizeof(struct thread_struct) ||
            sp > stack_end - STACK_FRAME_MIN_SIZE) {
                return 1;
        }
 
-       for (;;) {
+       for (firstframe = true; sp != stack_end;
+            firstframe = false, sp = newsp) {
                unsigned long *stack = (unsigned long *) sp;
-               unsigned long newsp, ip;
+               unsigned long ip;
 
                /* sanity check: ABI requires SP to be aligned 16 bytes. */
                if (sp & 0xF)
@@ -163,10 +160,8 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk,
                 * rest of the frame may be uninitialized, continue to
                 * the next.
                 */
-               if (firstframe) {
-                       firstframe = 0;
-                       goto next;
-               }
+               if (firstframe)
+                       continue;
 
                /* Mark stacktraces with exception frames as unreliable. */
                if (sp <= stack_end - STACK_INT_FRAME_SIZE &&
@@ -193,19 +188,12 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk,
                        return 1;
 #endif
 
+               if (trace->nr_entries >= trace->max_entries)
+                       return -E2BIG;
                if (!trace->skip)
                        trace->entries[trace->nr_entries++] = ip;
                else
                        trace->skip--;
-
-next:
-               if (newsp == stack_end)
-                       break;
-
-               if (trace->nr_entries >= trace->max_entries)
-                       return -E2BIG;
-
-               sp = newsp;
        }
        return 0;
 }
-- 
2.20.1

Reply via email to