[RFC PATCH v1 28/31] ARC: split ret_from_fork, simplify kernel_thread()

From: Vineet Gupta
Date: Wed Nov 07 2012 - 04:57:37 EST


Signed-off-by: Vineet Gupta <vgupta@xxxxxxxxxxxx>
---
arch/arc/kernel/entry.S | 8 ++++++++
arch/arc/kernel/process.c | 32 +++++++++++++-------------------
2 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index fe9a17c..46d0280 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -580,6 +580,14 @@ ARC_ENTRY ret_from_fork
b @ret_from_exception
ARC_EXIT ret_from_fork

+ARC_ENTRY ret_from_kernel_thread
+ bl @schedule_tail
+ ld r1, [sp, PT_r1]
+ j.d [r1]
+ ld r0, [sp, PT_r0]
+ j @sys_exit
+ARC_EXIT ret_from_kernel_thread
+
;################### Special Sys Call Wrappers ##########################

ARC_ENTRY sys_execve_wrapper
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index c116fa5..fee3e11 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -142,24 +142,13 @@ void cpu_idle(void)
}
}

-void kernel_thread_helper(void)
-{
- __asm__ __volatile__(
- "mov r0, r2 \n\t"
- "mov r1, r3 \n\t"
- "j [r1] \n\t");
-}
-
int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags)
{
- struct pt_regs regs;
+ struct pt_regs regs = {
+ .r0 = (unsigned long)arg,
+ .r1 = (unsigned long)fn
+ };

- memset(&regs, 0, sizeof(regs));
-
- regs.r2 = (unsigned long)arg;
- regs.r3 = (unsigned long)fn;
- regs.blink = (unsigned long)do_exit;
- regs.ret = (unsigned long)kernel_thread_helper;
regs.status32 = read_aux_reg(0xa);

/* Ok, create the new process.. */
@@ -170,6 +159,7 @@ int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags)
EXPORT_SYMBOL(kernel_thread);

asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void) __attribute__((noreturn));

/* Layout of Child kernel mode stack as setup at the end of this function is
*
@@ -226,18 +216,22 @@ int copy_thread(unsigned long clone_flags,
/* Copy parents pt regs on child's kernel mode stack */
*c_regs = *regs;

- /* __switch_to expects FP(0), BLINK(return addr) at top of stack */
- childksp[0] = 0; /* for POP fp */
- childksp[1] = (unsigned long)ret_from_fork; /* for POP blink */
-
if (!(user_mode(regs))) {
c_regs->sp =
(unsigned long)task_thread_info(p) + (THREAD_SIZE - 4);
+
+ /* __switch_to expects FP(0), BLINK(return addr) at top */
+ childksp[0] = 0; /* fp */
+ childksp[1] = (unsigned long)ret_from_kernel_thread; /* blink */
return 0;
}

/*--------- User Task Only --------------*/

+ /* __switch_to expects FP(0), BLINK(return addr) at top of stack */
+ childksp[0] = 0; /* for POP fp */
+ childksp[1] = (unsigned long)ret_from_fork; /* for POP blink */
+
c_regs->sp = usp;
c_regs->r0 = 0; /* fork returns 0 in child */

--
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/