aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2009-06-19 11:43:08 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-06-19 11:44:23 -0400
commitfeb97c3644a560ffdf9a17c65b1df807b5b4432f (patch)
treed9c84b8ad646cbf43e20c9a96e5db25b4ccd4ec6 /arch/arm/kernel
parentc894ed6956f126d60d888e8efc5fb3a595ba89ae (diff)
[ARM] 5559/1: Limit the stack unwinding caused by a kthread exit
When a kthread function returns, it branches to do_exit(). However, the unwinding information isn't valid anymore and any stack trace caused by do_exit() may be incorrect. This patch adds a kernel_thread_exit() function and annotated with '.cantunwind' so that the unwinder stops when reaching it. Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/process.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 1585423699ee..56820cce91a4 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -352,6 +352,23 @@ asm( ".section .text\n"
352" .size kernel_thread_helper, . - kernel_thread_helper\n" 352" .size kernel_thread_helper, . - kernel_thread_helper\n"
353" .previous"); 353" .previous");
354 354
355#ifdef CONFIG_ARM_UNWIND
356extern void kernel_thread_exit(long code);
357asm( ".section .text\n"
358" .align\n"
359" .type kernel_thread_exit, #function\n"
360"kernel_thread_exit:\n"
361" .fnstart\n"
362" .cantunwind\n"
363" bl do_exit\n"
364" nop\n"
365" .fnend\n"
366" .size kernel_thread_exit, . - kernel_thread_exit\n"
367" .previous");
368#else
369#define kernel_thread_exit do_exit
370#endif
371
355/* 372/*
356 * Create a kernel thread. 373 * Create a kernel thread.
357 */ 374 */
@@ -363,7 +380,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
363 380
364 regs.ARM_r1 = (unsigned long)arg; 381 regs.ARM_r1 = (unsigned long)arg;
365 regs.ARM_r2 = (unsigned long)fn; 382 regs.ARM_r2 = (unsigned long)fn;
366 regs.ARM_r3 = (unsigned long)do_exit; 383 regs.ARM_r3 = (unsigned long)kernel_thread_exit;
367 regs.ARM_pc = (unsigned long)kernel_thread_helper; 384 regs.ARM_pc = (unsigned long)kernel_thread_helper;
368 regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE; 385 regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE;
369 386