summaryrefslogtreecommitdiffstats
path: root/arch/h8300/kernel/process.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 12:22:13 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 12:22:13 -0800
commit9977d9b379cb77e0f67bd6f4563618106e58e11d (patch)
tree0191accfddf578edb52c69c933d64521e3dce297 /arch/h8300/kernel/process.c
parentcf4af01221579a4e895f43dbfc47598fbfc5a731 (diff)
parent541880d9a2c7871f6370071d55aa6662d329c51e (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull big execve/kernel_thread/fork unification series from Al Viro: "All architectures are converted to new model. Quite a bit of that stuff is actually shared with architecture trees; in such cases it's literally shared branch pulled by both, not a cherry-pick. A lot of ugliness and black magic is gone (-3KLoC total in this one): - kernel_thread()/kernel_execve()/sys_execve() redesign. We don't do syscalls from kernel anymore for either kernel_thread() or kernel_execve(): kernel_thread() is essentially clone(2) with callback run before we return to userland, the callbacks either never return or do successful do_execve() before returning. kernel_execve() is a wrapper for do_execve() - it doesn't need to do transition to user mode anymore. As a result kernel_thread() and kernel_execve() are arch-independent now - they live in kernel/fork.c and fs/exec.c resp. sys_execve() is also in fs/exec.c and it's completely architecture-independent. - daemonize() is gone, along with its parts in fs/*.c - struct pt_regs * is no longer passed to do_fork/copy_process/ copy_thread/do_execve/search_binary_handler/->load_binary/do_coredump. - sys_fork()/sys_vfork()/sys_clone() unified; some architectures still need wrappers (ones with callee-saved registers not saved in pt_regs on syscall entry), but the main part of those suckers is in kernel/fork.c now." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (113 commits) do_coredump(): get rid of pt_regs argument print_fatal_signal(): get rid of pt_regs argument ptrace_signal(): get rid of unused arguments get rid of ptrace_signal_deliver() arguments new helper: signal_pt_regs() unify default ptrace_signal_deliver flagday: kill pt_regs argument of do_fork() death to idle_regs() don't pass regs to copy_process() flagday: don't pass regs to copy_thread() bfin: switch to generic vfork, get rid of pointless wrappers xtensa: switch to generic clone() openrisc: switch to use of generic fork and clone unicore32: switch to generic clone(2) score: switch to generic fork/vfork/clone c6x: sanitize copy_thread(), get rid of clone(2) wrapper, switch to generic clone() take sys_fork/sys_vfork/sys_clone prototypes to linux/syscalls.h mn10300: switch to generic fork/vfork/clone h8300: switch to generic fork/vfork/clone tile: switch to generic clone() ... Conflicts: arch/microblaze/include/asm/Kbuild
Diffstat (limited to 'arch/h8300/kernel/process.c')
-rw-r--r--arch/h8300/kernel/process.c100
1 files changed, 11 insertions, 89 deletions
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index e8dc1393a13..b609f63f159 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -47,6 +47,7 @@ void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);
asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
/*
* The idle loop on an H8/300..
@@ -122,113 +123,34 @@ void show_regs(struct pt_regs * regs)
printk("\n");
}
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- long retval;
- long clone_arg;
- mm_segment_t fs;
-
- fs = get_fs();
- set_fs (KERNEL_DS);
- clone_arg = flags | CLONE_VM;
- __asm__("mov.l sp,er3\n\t"
- "sub.l er2,er2\n\t"
- "mov.l %2,er1\n\t"
- "mov.l %1,er0\n\t"
- "trapa #0\n\t"
- "cmp.l sp,er3\n\t"
- "beq 1f\n\t"
- "mov.l %4,er0\n\t"
- "mov.l %3,er1\n\t"
- "jsr @er1\n\t"
- "mov.l %5,er0\n\t"
- "trapa #0\n"
- "1:\n\t"
- "mov.l er0,%0"
- :"=r"(retval)
- :"i"(__NR_clone),"g"(clone_arg),"g"(fn),"g"(arg),"i"(__NR_exit)
- :"er0","er1","er2","er3");
- set_fs (fs);
- return retval;
-}
-
void flush_thread(void)
{
}
-/*
- * "h8300_fork()".. By the time we get here, the
- * non-volatile registers have also been saved on the
- * stack. We do some ugly pointer stuff here.. (see
- * also copy_thread)
- */
-
-asmlinkage int h8300_fork(struct pt_regs *regs)
-{
- return -EINVAL;
-}
-
-asmlinkage int h8300_vfork(struct pt_regs *regs)
-{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
-}
-
-asmlinkage int h8300_clone(struct pt_regs *regs)
-{
- unsigned long clone_flags;
- unsigned long newsp;
-
- /* syscall2 puts clone_flags in er1 and usp in er2 */
- clone_flags = regs->er1;
- newsp = regs->er2;
- if (!newsp)
- newsp = rdusp();
- return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
-
-}
-
int copy_thread(unsigned long clone_flags,
unsigned long usp, unsigned long topstk,
- struct task_struct * p, struct pt_regs * regs)
+ struct task_struct * p)
{
struct pt_regs * childregs;
childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
- *childregs = *regs;
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ memset(childregs, 0, sizeof(struct pt_regs));
+ childregs->retpc = (unsigned long) ret_from_kernel_thread;
+ childregs->er4 = topstk; /* arg */
+ childregs->er5 = usp; /* fn */
+ p->thread.ksp = (unsigned long)childregs;
+ }
+ *childregs = *current_pt_regs();
childregs->retpc = (unsigned long) ret_from_fork;
childregs->er0 = 0;
-
- p->thread.usp = usp;
+ p->thread.usp = usp ?: rdusp();
p->thread.ksp = (unsigned long)childregs;
return 0;
}
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char *name,
- const char *const *argv,
- const char *const *envp,
- int dummy, ...)
-{
- int error;
- struct filename *filename;
- struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename->name, argv, envp, regs);
- putname(filename);
- return error;
-}
-
unsigned long thread_saved_pc(struct task_struct *tsk)
{
return ((struct pt_regs *)tsk->thread.esp0)->pc;