فهرست منبع

[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>
Catalin Marinas 16 سال پیش
والد
کامیت
feb97c3644
1فایلهای تغییر یافته به همراه18 افزوده شده و 1 حذف شده
  1. 18 1
      arch/arm/kernel/process.c

+ 18 - 1
arch/arm/kernel/process.c

@@ -352,6 +352,23 @@ asm(	".section .text\n"
 "	.size	kernel_thread_helper, . - kernel_thread_helper\n"
 "	.previous");
 
+#ifdef CONFIG_ARM_UNWIND
+extern void kernel_thread_exit(long code);
+asm(	".section .text\n"
+"	.align\n"
+"	.type	kernel_thread_exit, #function\n"
+"kernel_thread_exit:\n"
+"	.fnstart\n"
+"	.cantunwind\n"
+"	bl	do_exit\n"
+"	nop\n"
+"	.fnend\n"
+"	.size	kernel_thread_exit, . - kernel_thread_exit\n"
+"	.previous");
+#else
+#define kernel_thread_exit	do_exit
+#endif
+
 /*
  * Create a kernel thread.
  */
@@ -363,7 +380,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 
 	regs.ARM_r1 = (unsigned long)arg;
 	regs.ARM_r2 = (unsigned long)fn;
-	regs.ARM_r3 = (unsigned long)do_exit;
+	regs.ARM_r3 = (unsigned long)kernel_thread_exit;
 	regs.ARM_pc = (unsigned long)kernel_thread_helper;
 	regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE;