aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 15:22:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 15:22:13 -0500
commit9977d9b379cb77e0f67bd6f4563618106e58e11d (patch)
tree0191accfddf578edb52c69c933d64521e3dce297 /arch/avr32
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/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
17 select GENERIC_CLOCKEVENTS 17 select GENERIC_CLOCKEVENTS
18 select HAVE_MOD_ARCH_SPECIFIC 18 select HAVE_MOD_ARCH_SPECIFIC
19 select MODULES_USE_ELF_RELA 19 select MODULES_USE_ELF_RELA
20 select GENERIC_KERNEL_THREAD
21 select GENERIC_KERNEL_EXECVE
20 help 22 help
21 AVR32 is a high-performance 32-bit RISC microprocessor core, 23 AVR32 is a high-performance 32-bit RISC microprocessor core,
22 designed for cost-sensitive embedded applications, with particular 24 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;
142/* Free all resources held by a thread */ 142/* Free all resources held by a thread */
143extern void release_thread(struct task_struct *); 143extern void release_thread(struct task_struct *);
144 144
145/* Create a kernel thread without removing it from tasklists */
146extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
147
148/* Return saved PC of a blocked thread */ 145/* Return saved PC of a blocked thread */
149#define thread_saved_pc(tsk) ((tsk)->thread.cpu_context.pc) 146#define thread_saved_pc(tsk) ((tsk)->thread.cpu_context.pc)
150 147
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 {
37#include <asm/sigcontext.h> 37#include <asm/sigcontext.h>
38#undef __HAVE_ARCH_SIG_BITOPS 38#undef __HAVE_ARCH_SIG_BITOPS
39 39
40#define ptrace_signal_deliver(regs, cookie) do { } while (0)
41
42#endif 40#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 @@
39#define __ARCH_WANT_SYS_GETPGRP 39#define __ARCH_WANT_SYS_GETPGRP
40#define __ARCH_WANT_SYS_RT_SIGACTION 40#define __ARCH_WANT_SYS_RT_SIGACTION
41#define __ARCH_WANT_SYS_RT_SIGSUSPEND 41#define __ARCH_WANT_SYS_RT_SIGSUSPEND
42#define __ARCH_WANT_SYS_EXECVE
43#define __ARCH_WANT_SYS_FORK
44#define __ARCH_WANT_SYS_VFORK
45#define __ARCH_WANT_SYS_CLONE
42 46
43/* 47/*
44 * "Conditional" syscalls 48 * "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
7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o 7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o
8obj-y += syscall_table.o syscall-stubs.o irq.o 8obj-y += syscall_table.o syscall-stubs.o irq.o
9obj-y += setup.o traps.o ocd.o ptrace.o 9obj-y += setup.o traps.o ocd.o ptrace.o
10obj-y += signal.o sys_avr32.o process.o time.o 10obj-y += signal.o process.o time.o
11obj-y += switch_to.o cpu.o 11obj-y += switch_to.o cpu.o
12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o 12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
13obj-$(CONFIG_KPROBES) += kprobes.o 13obj-$(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:
251 .global ret_from_fork 251 .global ret_from_fork
252ret_from_fork: 252ret_from_fork:
253 call schedule_tail 253 call schedule_tail
254 mov r12, 0
255 rjmp syscall_return
254 256
255 /* check for syscall tracing */ 257 .global ret_from_kernel_thread
256 get_thread_info r0 258ret_from_kernel_thread:
257 ld.w r1, r0[TI_flags] 259 call schedule_tail
258 andl r1, _TIF_ALLWORK_MASK, COH 260 mov r12, r0
259 brne syscall_exit_work 261 mov lr, r2 /* syscall_return */
260 rjmp syscall_exit_cont 262 mov pc, r1
261 263
262syscall_trace_enter: 264syscall_trace_enter:
263 pushm r8-r12 265 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)
69} 69}
70 70
71/* 71/*
72 * PC is actually discarded when returning from a system call -- the
73 * return address must be stored in LR. This function will make sure
74 * LR points to do_exit before starting the thread.
75 *
76 * Also, when returning from fork(), r12 is 0, so we must copy the
77 * argument as well.
78 *
79 * r0 : The argument to the main thread function
80 * r1 : The address of do_exit
81 * r2 : The address of the main thread function
82 */
83asmlinkage extern void kernel_thread_helper(void);
84__asm__(" .type kernel_thread_helper, @function\n"
85 "kernel_thread_helper:\n"
86 " mov r12, r0\n"
87 " mov lr, r2\n"
88 " mov pc, r1\n"
89 " .size kernel_thread_helper, . - kernel_thread_helper");
90
91int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
92{
93 struct pt_regs regs;
94
95 memset(&regs, 0, sizeof(regs));
96
97 regs.r0 = (unsigned long)arg;
98 regs.r1 = (unsigned long)fn;
99 regs.r2 = (unsigned long)do_exit;
100 regs.lr = (unsigned long)kernel_thread_helper;
101 regs.pc = (unsigned long)kernel_thread_helper;
102 regs.sr = MODE_SUPERVISOR;
103
104 return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
105 0, &regs, 0, NULL, NULL);
106}
107EXPORT_SYMBOL(kernel_thread);
108
109/*
110 * Free current thread data structures etc 72 * Free current thread data structures etc
111 */ 73 */
112void exit_thread(void) 74void exit_thread(void)
@@ -332,26 +294,32 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
332} 294}
333 295
334asmlinkage void ret_from_fork(void); 296asmlinkage void ret_from_fork(void);
297asmlinkage void ret_from_kernel_thread(void);
298asmlinkage void syscall_return(void);
335 299
336int copy_thread(unsigned long clone_flags, unsigned long usp, 300int copy_thread(unsigned long clone_flags, unsigned long usp,
337 unsigned long unused, 301 unsigned long arg,
338 struct task_struct *p, struct pt_regs *regs) 302 struct task_struct *p)
339{ 303{
340 struct pt_regs *childregs; 304 struct pt_regs *childregs = task_pt_regs(p);
341 305
342 childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)task_stack_page(p))) - 1; 306 if (unlikely(p->flags & PF_KTHREAD)) {
343 *childregs = *regs; 307 memset(childregs, 0, sizeof(struct pt_regs));
344 308 p->thread.cpu_context.r0 = arg;
345 if (user_mode(regs)) 309 p->thread.cpu_context.r1 = usp; /* fn */
346 childregs->sp = usp; 310 p->thread.cpu_context.r2 = syscall_return;
347 else 311 p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread;
348 childregs->sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; 312 childregs->sr = MODE_SUPERVISOR;
349 313 } else {
350 childregs->r12 = 0; /* Set return value for child */ 314 *childregs = *current_pt_regs();
315 if (usp)
316 childregs->sp = usp;
317 childregs->r12 = 0; /* Set return value for child */
318 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
319 }
351 320
352 p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM; 321 p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM;
353 p->thread.cpu_context.ksp = (unsigned long)childregs; 322 p->thread.cpu_context.ksp = (unsigned long)childregs;
354 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
355 323
356 clear_tsk_thread_flag(p, TIF_DEBUG); 324 clear_tsk_thread_flag(p, TIF_DEBUG);
357 if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) 325 if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG))
@@ -360,49 +328,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
360 return 0; 328 return 0;
361} 329}
362 330
363/* r12-r8 are dummy parameters to force the compiler to use the stack */
364asmlinkage int sys_fork(struct pt_regs *regs)
365{
366 return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
367}
368
369asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
370 void __user *parent_tidptr, void __user *child_tidptr,
371 struct pt_regs *regs)
372{
373 if (!newsp)
374 newsp = regs->sp;
375 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr,
376 child_tidptr);
377}
378
379asmlinkage int sys_vfork(struct pt_regs *regs)
380{
381 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs,
382 0, NULL, NULL);
383}
384
385asmlinkage int sys_execve(const char __user *ufilename,
386 const char __user *const __user *uargv,
387 const char __user *const __user *uenvp,
388 struct pt_regs *regs)
389{
390 int error;
391 struct filename *filename;
392
393 filename = getname(ufilename);
394 error = PTR_ERR(filename);
395 if (IS_ERR(filename))
396 goto out;
397
398 error = do_execve(filename->name, uargv, uenvp, regs);
399 putname(filename);
400
401out:
402 return error;
403}
404
405
406/* 331/*
407 * This function is supposed to answer the question "who called 332 * This function is supposed to answer the question "who called
408 * schedule()?" 333 * 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 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/unistd.h>
9
10int kernel_execve(const char *file,
11 const char *const *argv,
12 const char *const *envp)
13{
14 register long scno asm("r8") = __NR_execve;
15 register long sc1 asm("r12") = (long)file;
16 register long sc2 asm("r11") = (long)argv;
17 register long sc3 asm("r10") = (long)envp;
18
19 asm volatile("scall"
20 : "=r"(sc1)
21 : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
22 : "cc", "memory");
23 return sc1;
24}
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:
32 mov r12, sp 32 mov r12, sp
33 rjmp sys_rt_sigreturn 33 rjmp sys_rt_sigreturn
34 34
35 .global __sys_fork
36 .type __sys_fork,@function
37__sys_fork:
38 mov r12, sp
39 rjmp sys_fork
40
41 .global __sys_clone
42 .type __sys_clone,@function
43__sys_clone:
44 mov r8, sp
45 rjmp sys_clone
46
47 .global __sys_vfork
48 .type __sys_vfork,@function
49__sys_vfork:
50 mov r12, sp
51 rjmp sys_vfork
52
53 .global __sys_execve
54 .type __sys_execve,@function
55__sys_execve:
56 mov r9, sp
57 rjmp sys_execve
58
59 .global __sys_mmap2 35 .global __sys_mmap2
60 .type __sys_mmap2,@function 36 .type __sys_mmap2,@function
61__sys_mmap2: 37__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 @@
15sys_call_table: 15sys_call_table:
16 .long sys_restart_syscall 16 .long sys_restart_syscall
17 .long sys_exit 17 .long sys_exit
18 .long __sys_fork 18 .long sys_fork
19 .long sys_read 19 .long sys_read
20 .long sys_write 20 .long sys_write
21 .long sys_open /* 5 */ 21 .long sys_open /* 5 */
@@ -24,7 +24,7 @@ sys_call_table:
24 .long sys_creat 24 .long sys_creat
25 .long sys_link 25 .long sys_link
26 .long sys_unlink /* 10 */ 26 .long sys_unlink /* 10 */
27 .long __sys_execve 27 .long sys_execve
28 .long sys_chdir 28 .long sys_chdir
29 .long sys_time 29 .long sys_time
30 .long sys_mknod 30 .long sys_mknod
@@ -57,7 +57,7 @@ sys_call_table:
57 .long sys_dup 57 .long sys_dup
58 .long sys_pipe 58 .long sys_pipe
59 .long sys_times 59 .long sys_times
60 .long __sys_clone 60 .long sys_clone
61 .long sys_brk /* 45 */ 61 .long sys_brk /* 45 */
62 .long sys_setgid 62 .long sys_setgid
63 .long sys_getgid 63 .long sys_getgid
@@ -127,7 +127,7 @@ sys_call_table:
127 .long sys_newuname 127 .long sys_newuname
128 .long sys_adjtimex 128 .long sys_adjtimex
129 .long sys_mprotect 129 .long sys_mprotect
130 .long __sys_vfork 130 .long sys_vfork
131 .long sys_init_module /* 115 */ 131 .long sys_init_module /* 115 */
132 .long sys_delete_module 132 .long sys_delete_module
133 .long sys_quotactl 133 .long sys_quotactl