summaryrefslogtreecommitdiffstats
path: root/arch/avr32
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/avr32
parentcf4af01221579a4e895f43dbfc47598fbfc5a731 (diff)
parent541880d9a2c7871f6370071d55aa6662d329c51e (diff)
downloadlinux-stable-9977d9b379cb77e0f67bd6f4563618106e58e11d.tar.gz
linux-stable-9977d9b379cb77e0f67bd6f4563618106e58e11d.tar.bz2
linux-stable-9977d9b379cb77e0f67bd6f4563618106e58e11d.zip
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/avr32')
-rw-r--r--arch/avr32/Kconfig2
-rw-r--r--arch/avr32/include/asm/processor.h3
-rw-r--r--arch/avr32/include/asm/signal.h2
-rw-r--r--arch/avr32/include/asm/unistd.h4
-rw-r--r--arch/avr32/kernel/Makefile2
-rw-r--r--arch/avr32/kernel/entry-avr32b.S14
-rw-r--r--arch/avr32/kernel/process.c115
-rw-r--r--arch/avr32/kernel/sys_avr32.c24
-rw-r--r--arch/avr32/kernel/syscall-stubs.S24
-rw-r--r--arch/avr32/kernel/syscall_table.S8
10 files changed, 39 insertions, 159 deletions
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index c2bbc9a72222..202d71a15be1 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -17,6 +17,8 @@ config AVR32
select GENERIC_CLOCKEVENTS
select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_RELA
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
help
AVR32 is a high-performance 32-bit RISC microprocessor core,
designed for cost-sensitive embedded applications, with particular
diff --git a/arch/avr32/include/asm/processor.h b/arch/avr32/include/asm/processor.h
index 87d8baccc60e..48d71c5c898a 100644
--- a/arch/avr32/include/asm/processor.h
+++ b/arch/avr32/include/asm/processor.h
@@ -142,9 +142,6 @@ struct task_struct;
/* Free all resources held by a thread */
extern void release_thread(struct task_struct *);
-/* Create a kernel thread without removing it from tasklists */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
/* Return saved PC of a blocked thread */
#define thread_saved_pc(tsk) ((tsk)->thread.cpu_context.pc)
diff --git a/arch/avr32/include/asm/signal.h b/arch/avr32/include/asm/signal.h
index 4d502fd6bad3..9326d182e9e5 100644
--- a/arch/avr32/include/asm/signal.h
+++ b/arch/avr32/include/asm/signal.h
@@ -37,6 +37,4 @@ struct k_sigaction {
#include <asm/sigcontext.h>
#undef __HAVE_ARCH_SIG_BITOPS
-#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-
#endif
diff --git a/arch/avr32/include/asm/unistd.h b/arch/avr32/include/asm/unistd.h
index 157b4bd3d5e5..f05a9804e8e2 100644
--- a/arch/avr32/include/asm/unistd.h
+++ b/arch/avr32/include/asm/unistd.h
@@ -39,6 +39,10 @@
#define __ARCH_WANT_SYS_GETPGRP
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_SYS_FORK
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_CLONE
/*
* "Conditional" syscalls
diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile
index 9e2c465ef3a6..119a2e41defe 100644
--- a/arch/avr32/kernel/Makefile
+++ b/arch/avr32/kernel/Makefile
@@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds
obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o
obj-y += syscall_table.o syscall-stubs.o irq.o
obj-y += setup.o traps.o ocd.o ptrace.o
-obj-y += signal.o sys_avr32.o process.o time.o
+obj-y += signal.o process.o time.o
obj-y += switch_to.o cpu.o
obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
obj-$(CONFIG_KPROBES) += kprobes.o
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index df2884181313..9899d3cc6f03 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -251,13 +251,15 @@ syscall_badsys:
.global ret_from_fork
ret_from_fork:
call schedule_tail
+ mov r12, 0
+ rjmp syscall_return
- /* check for syscall tracing */
- get_thread_info r0
- ld.w r1, r0[TI_flags]
- andl r1, _TIF_ALLWORK_MASK, COH
- brne syscall_exit_work
- rjmp syscall_exit_cont
+ .global ret_from_kernel_thread
+ret_from_kernel_thread:
+ call schedule_tail
+ mov r12, r0
+ mov lr, r2 /* syscall_return */
+ mov pc, r1
syscall_trace_enter:
pushm r8-r12
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 1bb0a8abd79b..fd78f58ea79a 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -69,44 +69,6 @@ void machine_restart(char *cmd)
}
/*
- * PC is actually discarded when returning from a system call -- the
- * return address must be stored in LR. This function will make sure
- * LR points to do_exit before starting the thread.
- *
- * Also, when returning from fork(), r12 is 0, so we must copy the
- * argument as well.
- *
- * r0 : The argument to the main thread function
- * r1 : The address of do_exit
- * r2 : The address of the main thread function
- */
-asmlinkage extern void kernel_thread_helper(void);
-__asm__(" .type kernel_thread_helper, @function\n"
- "kernel_thread_helper:\n"
- " mov r12, r0\n"
- " mov lr, r2\n"
- " mov pc, r1\n"
- " .size kernel_thread_helper, . - kernel_thread_helper");
-
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
-
- regs.r0 = (unsigned long)arg;
- regs.r1 = (unsigned long)fn;
- regs.r2 = (unsigned long)do_exit;
- regs.lr = (unsigned long)kernel_thread_helper;
- regs.pc = (unsigned long)kernel_thread_helper;
- regs.sr = MODE_SUPERVISOR;
-
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
- 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
-/*
* Free current thread data structures etc
*/
void exit_thread(void)
@@ -332,26 +294,32 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
}
asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
+asmlinkage void syscall_return(void);
int copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long unused,
- struct task_struct *p, struct pt_regs *regs)
+ unsigned long arg,
+ struct task_struct *p)
{
- struct pt_regs *childregs;
-
- childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)task_stack_page(p))) - 1;
- *childregs = *regs;
-
- if (user_mode(regs))
- childregs->sp = usp;
- else
- childregs->sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
-
- childregs->r12 = 0; /* Set return value for child */
+ struct pt_regs *childregs = task_pt_regs(p);
+
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ memset(childregs, 0, sizeof(struct pt_regs));
+ p->thread.cpu_context.r0 = arg;
+ p->thread.cpu_context.r1 = usp; /* fn */
+ p->thread.cpu_context.r2 = syscall_return;
+ p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread;
+ childregs->sr = MODE_SUPERVISOR;
+ } else {
+ *childregs = *current_pt_regs();
+ if (usp)
+ childregs->sp = usp;
+ childregs->r12 = 0; /* Set return value for child */
+ p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
+ }
p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM;
p->thread.cpu_context.ksp = (unsigned long)childregs;
- p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
clear_tsk_thread_flag(p, TIF_DEBUG);
if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG))
@@ -360,49 +328,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
return 0;
}
-/* r12-r8 are dummy parameters to force the compiler to use the stack */
-asmlinkage int sys_fork(struct pt_regs *regs)
-{
- return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
-}
-
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
- void __user *parent_tidptr, void __user *child_tidptr,
- struct pt_regs *regs)
-{
- if (!newsp)
- newsp = regs->sp;
- return do_fork(clone_flags, newsp, regs, 0, parent_tidptr,
- child_tidptr);
-}
-
-asmlinkage int sys_vfork(struct pt_regs *regs)
-{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs,
- 0, NULL, NULL);
-}
-
-asmlinkage int sys_execve(const char __user *ufilename,
- const char __user *const __user *uargv,
- const char __user *const __user *uenvp,
- struct pt_regs *regs)
-{
- int error;
- struct filename *filename;
-
- filename = getname(ufilename);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
-
- error = do_execve(filename->name, uargv, uenvp, regs);
- putname(filename);
-
-out:
- return error;
-}
-
-
/*
* This function is supposed to answer the question "who called
* schedule()?"
diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c
deleted file mode 100644
index 62635a09ae3e..000000000000
--- a/arch/avr32/kernel/sys_avr32.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2004-2006 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/unistd.h>
-
-int kernel_execve(const char *file,
- const char *const *argv,
- const char *const *envp)
-{
- register long scno asm("r8") = __NR_execve;
- register long sc1 asm("r12") = (long)file;
- register long sc2 asm("r11") = (long)argv;
- register long sc3 asm("r10") = (long)envp;
-
- asm volatile("scall"
- : "=r"(sc1)
- : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
- : "cc", "memory");
- return sc1;
-}
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S
index 0447a3e2ba64..275aab9731fd 100644
--- a/arch/avr32/kernel/syscall-stubs.S
+++ b/arch/avr32/kernel/syscall-stubs.S
@@ -32,30 +32,6 @@ __sys_rt_sigreturn:
mov r12, sp
rjmp sys_rt_sigreturn
- .global __sys_fork
- .type __sys_fork,@function
-__sys_fork:
- mov r12, sp
- rjmp sys_fork
-
- .global __sys_clone
- .type __sys_clone,@function
-__sys_clone:
- mov r8, sp
- rjmp sys_clone
-
- .global __sys_vfork
- .type __sys_vfork,@function
-__sys_vfork:
- mov r12, sp
- rjmp sys_vfork
-
- .global __sys_execve
- .type __sys_execve,@function
-__sys_execve:
- mov r9, sp
- rjmp sys_execve
-
.global __sys_mmap2
.type __sys_mmap2,@function
__sys_mmap2:
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S
index 6eba53530d1c..f27bb878da6b 100644
--- a/arch/avr32/kernel/syscall_table.S
+++ b/arch/avr32/kernel/syscall_table.S
@@ -15,7 +15,7 @@
sys_call_table:
.long sys_restart_syscall
.long sys_exit
- .long __sys_fork
+ .long sys_fork
.long sys_read
.long sys_write
.long sys_open /* 5 */
@@ -24,7 +24,7 @@ sys_call_table:
.long sys_creat
.long sys_link
.long sys_unlink /* 10 */
- .long __sys_execve
+ .long sys_execve
.long sys_chdir
.long sys_time
.long sys_mknod
@@ -57,7 +57,7 @@ sys_call_table:
.long sys_dup
.long sys_pipe
.long sys_times
- .long __sys_clone
+ .long sys_clone
.long sys_brk /* 45 */
.long sys_setgid
.long sys_getgid
@@ -127,7 +127,7 @@ sys_call_table:
.long sys_newuname
.long sys_adjtimex
.long sys_mprotect
- .long __sys_vfork
+ .long sys_vfork
.long sys_init_module /* 115 */
.long sys_delete_module
.long sys_quotactl