diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-20 09:28:25 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2012-09-27 12:04:55 -0400 |
commit | d2ce4e92fa4f79a5fdb4cc912b411280afe21697 (patch) | |
tree | d7b1cae518d150b30342cef8dfa1a76e82005d25 /arch | |
parent | f9a38eace4498a5e9f6d2cdfc879d5444edc3a5f (diff) |
um: kill thread->forking
we only use that to tell copy_thread() done by syscall from that
done by kernel_thread(). However, it's easier to do simply by
checking PF_KTHREAD in thread flags.
Merge sys_clone() guts for 32bit and 64bit, while we are at it...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/include/asm/processor-generic.h | 9 | ||||
-rw-r--r-- | arch/um/kernel/process.c | 8 | ||||
-rw-r--r-- | arch/um/kernel/syscall.c | 24 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/syscalls.h | 2 | ||||
-rw-r--r-- | arch/x86/um/sys_call_table_32.c | 2 | ||||
-rw-r--r-- | arch/x86/um/syscalls_32.c | 27 | ||||
-rw-r--r-- | arch/x86/um/syscalls_64.c | 23 |
7 files changed, 29 insertions, 66 deletions
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index 69f1c57a8d0d..33a6a2423bd2 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h | |||
@@ -20,14 +20,6 @@ struct mm_struct; | |||
20 | 20 | ||
21 | struct thread_struct { | 21 | struct thread_struct { |
22 | struct task_struct *saved_task; | 22 | struct task_struct *saved_task; |
23 | /* | ||
24 | * This flag is set to 1 before calling do_fork (and analyzed in | ||
25 | * copy_thread) to mark that we are begin called from userspace (fork / | ||
26 | * vfork / clone), and reset to 0 after. It is left to 0 when called | ||
27 | * from kernelspace (i.e. kernel_thread() or fork_idle(), | ||
28 | * as of 2.6.11). | ||
29 | */ | ||
30 | int forking; | ||
31 | struct pt_regs regs; | 23 | struct pt_regs regs; |
32 | int singlestep_syscall; | 24 | int singlestep_syscall; |
33 | void *fault_addr; | 25 | void *fault_addr; |
@@ -58,7 +50,6 @@ struct thread_struct { | |||
58 | 50 | ||
59 | #define INIT_THREAD \ | 51 | #define INIT_THREAD \ |
60 | { \ | 52 | { \ |
61 | .forking = 0, \ | ||
62 | .regs = EMPTY_REGS, \ | 53 | .regs = EMPTY_REGS, \ |
63 | .fault_addr = NULL, \ | 54 | .fault_addr = NULL, \ |
64 | .prev_sched = NULL, \ | 55 | .prev_sched = NULL, \ |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 57fc7028714a..c5f5afa50745 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
181 | struct pt_regs *regs) | 181 | struct pt_regs *regs) |
182 | { | 182 | { |
183 | void (*handler)(void); | 183 | void (*handler)(void); |
184 | int kthread = current->flags & PF_KTHREAD; | ||
184 | int ret = 0; | 185 | int ret = 0; |
185 | 186 | ||
186 | p->thread = (struct thread_struct) INIT_THREAD; | 187 | p->thread = (struct thread_struct) INIT_THREAD; |
187 | 188 | ||
188 | if (current->thread.forking) { | 189 | if (!kthread) { |
189 | memcpy(&p->thread.regs.regs, ®s->regs, | 190 | memcpy(&p->thread.regs.regs, ®s->regs, |
190 | sizeof(p->thread.regs.regs)); | 191 | sizeof(p->thread.regs.regs)); |
191 | PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); | 192 | PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); |
@@ -195,8 +196,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
195 | handler = fork_handler; | 196 | handler = fork_handler; |
196 | 197 | ||
197 | arch_copy_thread(¤t->thread.arch, &p->thread.arch); | 198 | arch_copy_thread(¤t->thread.arch, &p->thread.arch); |
198 | } | 199 | } else { |
199 | else { | ||
200 | get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); | 200 | get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); |
201 | p->thread.request.u.thread = current->thread.request.u.thread; | 201 | p->thread.request.u.thread = current->thread.request.u.thread; |
202 | handler = new_thread_handler; | 202 | handler = new_thread_handler; |
@@ -204,7 +204,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
204 | 204 | ||
205 | new_thread(task_stack_page(p), &p->thread.switch_buf, handler); | 205 | new_thread(task_stack_page(p), &p->thread.switch_buf, handler); |
206 | 206 | ||
207 | if (current->thread.forking) { | 207 | if (!kthread) { |
208 | clear_flushed_tls(p); | 208 | clear_flushed_tls(p); |
209 | 209 | ||
210 | /* | 210 | /* |
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index f958cb876ee3..a4c6d8eee74c 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
@@ -17,25 +17,25 @@ | |||
17 | 17 | ||
18 | long sys_fork(void) | 18 | long sys_fork(void) |
19 | { | 19 | { |
20 | long ret; | 20 | return do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), |
21 | |||
22 | current->thread.forking = 1; | ||
23 | ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), | ||
24 | ¤t->thread.regs, 0, NULL, NULL); | 21 | ¤t->thread.regs, 0, NULL, NULL); |
25 | current->thread.forking = 0; | ||
26 | return ret; | ||
27 | } | 22 | } |
28 | 23 | ||
29 | long sys_vfork(void) | 24 | long sys_vfork(void) |
30 | { | 25 | { |
31 | long ret; | 26 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, |
32 | |||
33 | current->thread.forking = 1; | ||
34 | ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, | ||
35 | UPT_SP(¤t->thread.regs.regs), | 27 | UPT_SP(¤t->thread.regs.regs), |
36 | ¤t->thread.regs, 0, NULL, NULL); | 28 | ¤t->thread.regs, 0, NULL, NULL); |
37 | current->thread.forking = 0; | 29 | } |
38 | return ret; | 30 | |
31 | long sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
32 | void __user *parent_tid, void __user *child_tid) | ||
33 | { | ||
34 | if (!newsp) | ||
35 | newsp = UPT_SP(¤t->thread.regs.regs); | ||
36 | |||
37 | return do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, | ||
38 | child_tid); | ||
39 | } | 39 | } |
40 | 40 | ||
41 | long old_mmap(unsigned long addr, unsigned long len, | 41 | long old_mmap(unsigned long addr, unsigned long len, |
diff --git a/arch/x86/um/shared/sysdep/syscalls.h b/arch/x86/um/shared/sysdep/syscalls.h index bd9a89b67e41..ca255a805ed9 100644 --- a/arch/x86/um/shared/sysdep/syscalls.h +++ b/arch/x86/um/shared/sysdep/syscalls.h | |||
@@ -1,3 +1,5 @@ | |||
1 | extern long sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
2 | void __user *parent_tid, void __user *child_tid); | ||
1 | #ifdef __i386__ | 3 | #ifdef __i386__ |
2 | #include "syscalls_32.h" | 4 | #include "syscalls_32.h" |
3 | #else | 5 | #else |
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c index 68d1dc91b37b..b5408cecac6c 100644 --- a/arch/x86/um/sys_call_table_32.c +++ b/arch/x86/um/sys_call_table_32.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #define ptregs_execve sys_execve | 28 | #define ptregs_execve sys_execve |
29 | #define ptregs_iopl sys_iopl | 29 | #define ptregs_iopl sys_iopl |
30 | #define ptregs_vm86old sys_vm86old | 30 | #define ptregs_vm86old sys_vm86old |
31 | #define ptregs_clone sys_clone | 31 | #define ptregs_clone i386_clone |
32 | #define ptregs_vm86 sys_vm86 | 32 | #define ptregs_vm86 sys_vm86 |
33 | #define ptregs_sigaltstack sys_sigaltstack | 33 | #define ptregs_sigaltstack sys_sigaltstack |
34 | #define ptregs_vfork sys_vfork | 34 | #define ptregs_vfork sys_vfork |
diff --git a/arch/x86/um/syscalls_32.c b/arch/x86/um/syscalls_32.c index b853e8600b9d..db444c7218fe 100644 --- a/arch/x86/um/syscalls_32.c +++ b/arch/x86/um/syscalls_32.c | |||
@@ -3,37 +3,24 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/sched.h" | 6 | #include <linux/syscalls.h> |
7 | #include "linux/shm.h" | 7 | #include <sysdep/syscalls.h> |
8 | #include "linux/ipc.h" | ||
9 | #include "linux/syscalls.h" | ||
10 | #include "asm/mman.h" | ||
11 | #include "asm/uaccess.h" | ||
12 | #include "asm/unistd.h" | ||
13 | 8 | ||
14 | /* | 9 | /* |
15 | * The prototype on i386 is: | 10 | * The prototype on i386 is: |
16 | * | 11 | * |
17 | * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) | 12 | * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls |
18 | * | 13 | * |
19 | * and the "newtls" arg. on i386 is read by copy_thread directly from the | 14 | * and the "newtls" arg. on i386 is read by copy_thread directly from the |
20 | * register saved on the stack. | 15 | * register saved on the stack. |
21 | */ | 16 | */ |
22 | long sys_clone(unsigned long clone_flags, unsigned long newsp, | 17 | long i386_clone(unsigned long clone_flags, unsigned long newsp, |
23 | int __user *parent_tid, void *newtls, int __user *child_tid) | 18 | int __user *parent_tid, void *newtls, int __user *child_tid) |
24 | { | 19 | { |
25 | long ret; | 20 | return sys_clone(clone_flags, newsp, parent_tid, child_tid); |
26 | |||
27 | if (!newsp) | ||
28 | newsp = UPT_SP(¤t->thread.regs.regs); | ||
29 | |||
30 | current->thread.forking = 1; | ||
31 | ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, | ||
32 | child_tid); | ||
33 | current->thread.forking = 0; | ||
34 | return ret; | ||
35 | } | 21 | } |
36 | 22 | ||
23 | |||
37 | long sys_sigaction(int sig, const struct old_sigaction __user *act, | 24 | long sys_sigaction(int sig, const struct old_sigaction __user *act, |
38 | struct old_sigaction __user *oact) | 25 | struct old_sigaction __user *oact) |
39 | { | 26 | { |
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c index f3d82bb6e15a..adb08eb5c22a 100644 --- a/arch/x86/um/syscalls_64.c +++ b/arch/x86/um/syscalls_64.c | |||
@@ -5,12 +5,9 @@ | |||
5 | * Licensed under the GPL | 5 | * Licensed under the GPL |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "linux/linkage.h" | 8 | #include <linux/sched.h> |
9 | #include "linux/personality.h" | 9 | #include <asm/prctl.h> /* XXX This should get the constants from libc */ |
10 | #include "linux/utsname.h" | 10 | #include <os.h> |
11 | #include "asm/prctl.h" /* XXX This should get the constants from libc */ | ||
12 | #include "asm/uaccess.h" | ||
13 | #include "os.h" | ||
14 | 11 | ||
15 | long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) | 12 | long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) |
16 | { | 13 | { |
@@ -79,20 +76,6 @@ long sys_arch_prctl(int code, unsigned long addr) | |||
79 | return arch_prctl(current, code, (unsigned long __user *) addr); | 76 | return arch_prctl(current, code, (unsigned long __user *) addr); |
80 | } | 77 | } |
81 | 78 | ||
82 | long sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
83 | void __user *parent_tid, void __user *child_tid) | ||
84 | { | ||
85 | long ret; | ||
86 | |||
87 | if (!newsp) | ||
88 | newsp = UPT_SP(¤t->thread.regs.regs); | ||
89 | current->thread.forking = 1; | ||
90 | ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, | ||
91 | child_tid); | ||
92 | current->thread.forking = 0; | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | void arch_switch_to(struct task_struct *to) | 79 | void arch_switch_to(struct task_struct *to) |
97 | { | 80 | { |
98 | if ((to->thread.arch.fs == 0) || (to->mm == NULL)) | 81 | if ((to->thread.arch.fs == 0) || (to->mm == NULL)) |