openrisc: pass correct arg to schedule_tail
authorJonas Bonn <jonas@southpole.se>
Sun, 14 Oct 2012 14:19:52 +0000 (16:19 +0200)
committerJonas Bonn <jonas@southpole.se>
Fri, 19 Oct 2012 16:32:36 +0000 (18:32 +0200)
schedule_tail() requires that the 'prev' task be passed as an argument
to it.  This arg is set in _switch, just before 'returning' to one of
the ret_* functions where schedule_tail is invoked.

Signed-off-by: Jonas Bonn <jonas@southpole.se>
arch/openrisc/kernel/entry.S
arch/openrisc/kernel/process.c

index ddfcaa8..374e63e 100644 (file)
@@ -1044,8 +1044,13 @@ ENTRY(_switch)
        /* Unwind stack to pre-switch state */
        l.addi  r1,r1,(INT_FRAME_SIZE)
 
-       /* Return via the link-register back to where we 'came from', where that can be
-        * either schedule() or return_from_fork()... */
+       /* Return via the link-register back to where we 'came from', where
+        * that may be either schedule(), ret_from_fork(), or
+        * ret_from_kernel_thread().  If we are returning to a new thread,
+        * we are expected to have set up the arg to schedule_tail already,
+        * hence we do so here unconditionally:
+        */
+       l.lwz   r3,TI_STACK(r3)         /* Load 'prev' as schedule_tail arg */
        l.jr    r9
         l.nop
 
index c35f3ab..ad26d5a 100644 (file)
@@ -165,7 +165,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
         * the kernel stack.
         */
        kregs->sp = top_of_kernel_stack;
-       kregs->gpr[3] = (unsigned long)current; /* arg to schedule_tail */
        kregs->gpr[10] = (unsigned long)task_thread_info(p);
        kregs->gpr[9] = (unsigned long)ret_from_fork;