]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/frv/kernel/process.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
[karo-tx-linux.git] / arch / frv / kernel / process.c
index 2eb7fa5bf9d8d48386ea7583dd1731dd92eff7a8..655d90d20bb0cad25df015e7bdc9dee6dbf4e37b 100644 (file)
@@ -38,6 +38,7 @@
 #include "local.h"
 
 asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
 
 #include <asm/pgalloc.h>
 
@@ -172,32 +173,13 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
  * set up the kernel stack and exception frames for a new process
  */
 int copy_thread(unsigned long clone_flags,
-               unsigned long usp, unsigned long topstk,
+               unsigned long usp, unsigned long arg,
                struct task_struct *p, struct pt_regs *regs)
 {
-       struct pt_regs *childregs0, *childregs, *regs0;
+       struct pt_regs *childregs;
 
-       regs0 = __kernel_frame0_ptr;
-       childregs0 = (struct pt_regs *)
+       childregs = (struct pt_regs *)
                (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
-       childregs = childregs0;
-
-       /* set up the userspace frame (the only place that the USP is stored) */
-       *childregs0 = *regs0;
-
-       childregs0->gr8         = 0;
-       childregs0->sp          = usp;
-       childregs0->next_frame  = NULL;
-
-       /* set up the return kernel frame if called from kernel_thread() */
-       if (regs != regs0) {
-               childregs--;
-               *childregs = *regs;
-               childregs->sp = (unsigned long) childregs0;
-               childregs->next_frame = childregs0;
-               childregs->gr15 = (unsigned long) task_thread_info(p);
-               childregs->gr29 = (unsigned long) p;
-       }
 
        p->set_child_tid = p->clear_child_tid = NULL;
 
@@ -206,8 +188,25 @@ int copy_thread(unsigned long clone_flags,
        p->thread.sp     = (unsigned long) childregs;
        p->thread.fp     = 0;
        p->thread.lr     = 0;
-       p->thread.pc     = (unsigned long) ret_from_fork;
-       p->thread.frame0 = childregs0;
+       p->thread.frame0 = childregs;
+
+       if (unlikely(!regs)) {
+               memset(childregs, 0, sizeof(struct pt_regs));
+               childregs->gr9 = usp; /* function */
+               childregs->gr8 = arg;
+               chilregs->psr = PSR_S;
+               p->thread.pc = (unsigned long) ret_from_kernel_thread;
+               save_user_regs(p->thread.user);
+               return 0;
+       }
+
+       /* set up the userspace frame (the only place that the USP is stored) */
+       *childregs = *regs;
+
+       childregs->sp           = usp;
+       childregs->next_frame   = NULL;
+
+       p->thread.pc = (unsigned long) ret_from_fork;
 
        /* the new TLS pointer is passed in as arg #5 to sys_clone() */
        if (clone_flags & CLONE_SETTLS)
@@ -218,25 +217,6 @@ int copy_thread(unsigned long clone_flags,
        return 0;
 } /* end copy_thread() */
 
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char __user *name,
-                         const char __user *const __user *argv,
-                         const char __user *const __user *envp)
-{
-       int error;
-       char * filename;
-
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, __frame);
-       putname(filename);
-       return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
        struct pt_regs *regs0;