From 29a77bbb0cf2cea41fa46f8fa176f6cb1e3182c4 Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Tue, 22 Jan 2019 10:57:23 -0500 Subject: [PATCH] powerpc/livepatch: small cleanups in save_stack_trace_tsk_reliable() 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 Signed-off-by: Joe Lawrence Signed-off-by: Michael Ellerman --- 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; }