powerpc: Use ftrace_graph_ret_addr() when unwinding
[linux-2.6-block.git] / arch / powerpc / kernel / process.c
index 8fc4de0d22b4ce9cf8b3bbf3e6906211172d6a07..f289bdd2b562c342086ee8bfaf849495d8cbcf46 100644 (file)
@@ -1600,8 +1600,9 @@ static void setup_ksp_vsid(struct task_struct *p, unsigned long sp)
 /*
  * Copy architecture-specific thread state
  */
-int copy_thread(unsigned long clone_flags, unsigned long usp,
-               unsigned long kthread_arg, struct task_struct *p)
+int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
+               unsigned long kthread_arg, struct task_struct *p,
+               unsigned long tls)
 {
        struct pt_regs *childregs, *kregs;
        extern void ret_from_fork(void);
@@ -1642,10 +1643,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
                if (clone_flags & CLONE_SETTLS) {
 #ifdef CONFIG_PPC64
                        if (!is_32bit_task())
-                               childregs->gpr[13] = childregs->gpr[6];
+                               childregs->gpr[13] = tls;
                        else
 #endif
-                               childregs->gpr[2] = childregs->gpr[6];
+                               childregs->gpr[2] = tls;
                }
 
                f = ret_from_fork;
@@ -2046,10 +2047,8 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
        int count = 0;
        int firstframe = 1;
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-       struct ftrace_ret_stack *ret_stack;
-       extern void return_to_handler(void);
-       unsigned long rth = (unsigned long)return_to_handler;
-       int curr_frame = 0;
+       unsigned long ret_addr;
+       int ftrace_idx = 0;
 #endif
 
        if (tsk == NULL)
@@ -2078,15 +2077,10 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
                if (!firstframe || ip != lr) {
                        printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-                       if ((ip == rth) && curr_frame >= 0) {
-                               ret_stack = ftrace_graph_get_ret_stack(current,
-                                                                 curr_frame++);
-                               if (ret_stack)
-                                       pr_cont(" (%pS)",
-                                               (void *)ret_stack->ret);
-                               else
-                                       curr_frame = -1;
-                       }
+                       ret_addr = ftrace_graph_ret_addr(current,
+                                               &ftrace_idx, ip, stack);
+                       if (ret_addr != ip)
+                               pr_cont(" (%pS)", (void *)ret_addr);
 #endif
                        if (firstframe)
                                pr_cont(" (unreliable)");