aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel/process.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-11 21:49:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-11 21:49:08 -0400
commit8213a2f3eeafdecf06dd718cb4130372263f6067 (patch)
tree0d02e3201dac64d1429f8552ee1163d4a1ef1646 /arch/mn10300/kernel/process.c
parent40924754f2cabd5d9af4bcd4dcecc362b5e0baa1 (diff)
parent12f79be93d94698778ff2b3f921073fc5f6780d6 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull pile 2 of execve and kernel_thread unification work from Al Viro: "Stuff in there: kernel_thread/kernel_execve/sys_execve conversions for several more architectures plus assorted signal fixes and cleanups. There'll be more (in particular, real fixes for the alpha do_notify_resume() irq mess)..." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (43 commits) alpha: don't open-code trace_report_syscall_{enter,exit} Uninclude linux/freezer.h m32r: trim masks avr32: trim masks tile: don't bother with SIGTRAP in setup_frame microblaze: don't bother with SIGTRAP in setup_rt_frame() mn10300: don't bother with SIGTRAP in setup_frame() frv: no need to raise SIGTRAP in setup_frame() x86: get rid of duplicate code in case of CONFIG_VM86 unicore32: remove pointless test h8300: trim _TIF_WORK_MASK parisc: decide whether to go to slow path (tracesys) based on thread flags parisc: don't bother looping in do_signal() parisc: fix double restarts bury the rest of TIF_IRET sanitize tsk_is_polling() bury _TIF_RESTORE_SIGMASK unicore32: unobfuscate _TIF_WORK_MASK mips: NOTIFY_RESUME is not needed in TIF masks mips: merge the identical "return from syscall" per-ABI code ... Conflicts: arch/arm/include/asm/thread_info.h
Diffstat (limited to 'arch/mn10300/kernel/process.c')
-rw-r--r--arch/mn10300/kernel/process.c91
1 files changed, 23 insertions, 68 deletions
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index e9cceba193b6..d0c671b6d9ff 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -165,27 +165,6 @@ void show_regs(struct pt_regs *regs)
165} 165}
166 166
167/* 167/*
168 * create a kernel thread
169 */
170int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
171{
172 struct pt_regs regs;
173
174 memset(&regs, 0, sizeof(regs));
175
176 regs.a2 = (unsigned long) fn;
177 regs.d2 = (unsigned long) arg;
178 regs.pc = (unsigned long) kernel_thread_helper;
179 local_save_flags(regs.epsw);
180 regs.epsw |= EPSW_IE | EPSW_IM_7;
181
182 /* Ok, create the new process.. */
183 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0,
184 NULL, NULL);
185}
186EXPORT_SYMBOL(kernel_thread);
187
188/*
189 * free current thread data structures etc.. 168 * free current thread data structures etc..
190 */ 169 */
191void exit_thread(void) 170void exit_thread(void)
@@ -230,50 +209,42 @@ int copy_thread(unsigned long clone_flags,
230 struct task_struct *p, struct pt_regs *kregs) 209 struct task_struct *p, struct pt_regs *kregs)
231{ 210{
232 struct thread_info *ti = task_thread_info(p); 211 struct thread_info *ti = task_thread_info(p);
233 struct pt_regs *c_uregs, *c_kregs, *uregs; 212 struct pt_regs *c_regs;
234 unsigned long c_ksp; 213 unsigned long c_ksp;
235 214
236 uregs = current->thread.uregs;
237
238 c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE; 215 c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;
239 216
240 /* allocate the userspace exception frame and set it up */ 217 /* allocate the userspace exception frame and set it up */
241 c_ksp -= sizeof(struct pt_regs); 218 c_ksp -= sizeof(struct pt_regs);
242 c_uregs = (struct pt_regs *) c_ksp; 219 c_regs = (struct pt_regs *) c_ksp;
220 c_ksp -= 12; /* allocate function call ABI slack */
243 221
244 p->thread.uregs = c_uregs; 222 /* set up things up so the scheduler can start the new task */
245 *c_uregs = *uregs; 223 p->thread.uregs = c_regs;
246 c_uregs->sp = c_usp; 224 ti->frame = c_regs;
247 c_uregs->epsw &= ~EPSW_FE; /* my FPU */ 225 p->thread.a3 = (unsigned long) c_regs;
226 p->thread.sp = c_ksp;
227 p->thread.wchan = p->thread.pc;
228 p->thread.usp = c_usp;
248 229
249 c_ksp -= 12; /* allocate function call ABI slack */ 230 if (unlikely(!kregs)) {
231 memset(c_regs, 0, sizeof(struct pt_regs));
232 c_regs->a0 = c_usp; /* function */
233 c_regs->d0 = ustk_size; /* argument */
234 local_save_flags(c_regs->epsw);
235 c_regs->epsw |= EPSW_IE | EPSW_IM_7;
236 p->thread.pc = (unsigned long) ret_from_kernel_thread;
237 return 0;
238 }
239 *c_regs = *kregs;
240 c_regs->sp = c_usp;
241 c_regs->epsw &= ~EPSW_FE; /* my FPU */
250 242
251 /* the new TLS pointer is passed in as arg #5 to sys_clone() */ 243 /* the new TLS pointer is passed in as arg #5 to sys_clone() */
252 if (clone_flags & CLONE_SETTLS) 244 if (clone_flags & CLONE_SETTLS)
253 c_uregs->e2 = current_frame()->d3; 245 c_regs->e2 = current_frame()->d3;
254
255 /* set up the return kernel frame if called from kernel_thread() */
256 c_kregs = c_uregs;
257 if (kregs != uregs) {
258 c_ksp -= sizeof(struct pt_regs);
259 c_kregs = (struct pt_regs *) c_ksp;
260 *c_kregs = *kregs;
261 c_kregs->sp = c_usp;
262 c_kregs->next = c_uregs;
263#ifdef CONFIG_MN10300_CURRENT_IN_E2
264 c_kregs->e2 = (unsigned long) p; /* current */
265#endif
266
267 c_ksp -= 12; /* allocate function call ABI slack */
268 }
269 246
270 /* set up things up so the scheduler can start the new task */
271 ti->frame = c_kregs;
272 p->thread.a3 = (unsigned long) c_kregs;
273 p->thread.sp = c_ksp;
274 p->thread.pc = (unsigned long) ret_from_fork; 247 p->thread.pc = (unsigned long) ret_from_fork;
275 p->thread.wchan = (unsigned long) ret_from_fork;
276 p->thread.usp = c_usp;
277 248
278 return 0; 249 return 0;
279} 250}
@@ -302,22 +273,6 @@ asmlinkage long sys_vfork(void)
302 current_frame(), 0, NULL, NULL); 273 current_frame(), 0, NULL, NULL);
303} 274}
304 275
305asmlinkage long sys_execve(const char __user *name,
306 const char __user *const __user *argv,
307 const char __user *const __user *envp)
308{
309 char *filename;
310 int error;
311
312 filename = getname(name);
313 error = PTR_ERR(filename);
314 if (IS_ERR(filename))
315 return error;
316 error = do_execve(filename, argv, envp, current_frame());
317 putname(filename);
318 return error;
319}
320
321unsigned long get_wchan(struct task_struct *p) 276unsigned long get_wchan(struct task_struct *p)
322{ 277{
323 return p->thread.wchan; 278 return p->thread.wchan;