diff options
Diffstat (limited to 'arch/frv/kernel/process.c')
| -rw-r--r-- | arch/frv/kernel/process.c | 46 |
1 files changed, 6 insertions, 40 deletions
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index e1e3aa196aa4..23916b2a12a2 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c | |||
| @@ -139,49 +139,20 @@ inline unsigned long user_stack(const struct pt_regs *regs) | |||
| 139 | return user_mode(regs) ? regs->sp : 0; | 139 | return user_mode(regs) ? regs->sp : 0; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | asmlinkage int sys_fork(void) | ||
| 143 | { | ||
| 144 | #ifndef CONFIG_MMU | ||
| 145 | /* fork almost works, enough to trick you into looking elsewhere:-( */ | ||
| 146 | return -EINVAL; | ||
| 147 | #else | ||
| 148 | return do_fork(SIGCHLD, user_stack(__frame), __frame, 0, NULL, NULL); | ||
| 149 | #endif | ||
| 150 | } | ||
| 151 | |||
| 152 | asmlinkage int sys_vfork(void) | ||
| 153 | { | ||
| 154 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, user_stack(__frame), __frame, 0, | ||
| 155 | NULL, NULL); | ||
| 156 | } | ||
| 157 | |||
| 158 | /*****************************************************************************/ | ||
| 159 | /* | ||
| 160 | * clone a process | ||
| 161 | * - tlsptr is retrieved by copy_thread() | ||
| 162 | */ | ||
| 163 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
| 164 | int __user *parent_tidptr, int __user *child_tidptr, | ||
| 165 | int __user *tlsptr) | ||
| 166 | { | ||
| 167 | if (!newsp) | ||
| 168 | newsp = user_stack(__frame); | ||
| 169 | return do_fork(clone_flags, newsp, __frame, 0, parent_tidptr, child_tidptr); | ||
| 170 | } /* end sys_clone() */ | ||
| 171 | |||
| 172 | /* | 142 | /* |
| 173 | * set up the kernel stack and exception frames for a new process | 143 | * set up the kernel stack and exception frames for a new process |
| 174 | */ | 144 | */ |
| 175 | int copy_thread(unsigned long clone_flags, | 145 | int copy_thread(unsigned long clone_flags, |
| 176 | unsigned long usp, unsigned long arg, | 146 | unsigned long usp, unsigned long arg, |
| 177 | struct task_struct *p, struct pt_regs *regs) | 147 | struct task_struct *p) |
| 178 | { | 148 | { |
| 179 | struct pt_regs *childregs; | 149 | struct pt_regs *childregs; |
| 180 | 150 | ||
| 181 | childregs = (struct pt_regs *) | 151 | childregs = (struct pt_regs *) |
| 182 | (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); | 152 | (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); |
| 183 | 153 | ||
| 184 | p->set_child_tid = p->clear_child_tid = NULL; | 154 | /* set up the userspace frame (the only place that the USP is stored) */ |
| 155 | *childregs = *current_pt_regs(); | ||
| 185 | 156 | ||
| 186 | p->thread.frame = childregs; | 157 | p->thread.frame = childregs; |
| 187 | p->thread.curr = p; | 158 | p->thread.curr = p; |
| @@ -190,20 +161,15 @@ int copy_thread(unsigned long clone_flags, | |||
| 190 | p->thread.lr = 0; | 161 | p->thread.lr = 0; |
| 191 | p->thread.frame0 = childregs; | 162 | p->thread.frame0 = childregs; |
| 192 | 163 | ||
| 193 | if (unlikely(!regs)) { | 164 | if (unlikely(p->flags & PF_KTHREAD)) { |
| 194 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
| 195 | childregs->gr9 = usp; /* function */ | 165 | childregs->gr9 = usp; /* function */ |
| 196 | childregs->gr8 = arg; | 166 | childregs->gr8 = arg; |
| 197 | childregs->psr = PSR_S; | ||
| 198 | p->thread.pc = (unsigned long) ret_from_kernel_thread; | 167 | p->thread.pc = (unsigned long) ret_from_kernel_thread; |
| 199 | save_user_regs(p->thread.user); | 168 | save_user_regs(p->thread.user); |
| 200 | return 0; | 169 | return 0; |
| 201 | } | 170 | } |
| 202 | 171 | if (usp) | |
| 203 | /* set up the userspace frame (the only place that the USP is stored) */ | 172 | childregs->sp = usp; |
| 204 | *childregs = *regs; | ||
| 205 | |||
| 206 | childregs->sp = usp; | ||
| 207 | childregs->next_frame = NULL; | 173 | childregs->next_frame = NULL; |
| 208 | 174 | ||
| 209 | p->thread.pc = (unsigned long) ret_from_fork; | 175 | p->thread.pc = (unsigned long) ret_from_fork; |
