History

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...

Al Viro committed 14 years ago

Commit d2ce4e91 parent f9a38ea7 files · +29 −66Browse files

Unified · Split

7 files
  1. arch/um/include/asm/processor-generic.h +0 −9
  2. arch/um/kernel/process.c +4 −4
  3. arch/um/kernel/syscall.c +12 −12
  4. arch/x86/um/shared/sysdep/syscalls.h +2 −0
  5. arch/x86/um/sys_call_table_32.c +1 −1
  6. arch/x86/um/syscalls_32.c +7 −20
  7. arch/x86/um/syscalls_64.c +3 −20
arch/um/include/asm/processor-generic.h+0−9
@@ -20,14 +20,6 @@ struct mm_struct; · 19 unmodified lines
20 20
21struct thread_struct {21struct 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 { · 24 unmodified lines
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, \
arch/um/kernel/process.c+4−4
@@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, · 180 unmodified lines
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, &regs->regs,190 memcpy(&p->thread.regs.regs, &regs->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, · 3 unmodified lines
195 handler = fork_handler;196 handler = fork_handler;
196 197
197 arch_copy_thread(&current->thread.arch, &p->thread.arch);198 arch_copy_thread(&current->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, · 1 unmodified line
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 /*
arch/um/kernel/syscall.c+12−12
@@ -17,25 +17,25 @@ · 16 unmodified lines
17 17
18long sys_fork(void)18long sys_fork(void)
19{19{
20 long ret;20 return do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
21
22 current->thread.forking = 1;
23 ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
24 &current->thread.regs, 0, NULL, NULL);21 &current->thread.regs, 0, NULL, NULL);
25 current->thread.forking = 0;
26 return ret;
27}22}
28 23
29long sys_vfork(void)24long 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(&current->thread.regs.regs),27 UPT_SP(&current->thread.regs.regs),
36 &current->thread.regs, 0, NULL, NULL);28 &current->thread.regs, 0, NULL, NULL);
37 current->thread.forking = 0;29}
38 return ret;30
31long 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(&current->thread.regs.regs);
36
37 return do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
38 child_tid);
39}39}
40 40
41long old_mmap(unsigned long addr, unsigned long len,41long old_mmap(unsigned long addr, unsigned long len,
arch/x86/um/shared/sysdep/syscalls.h+2−0
@@ -1,3 +1,5 @@
1extern 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#else5#else
arch/x86/um/sys_call_table_32.c+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
28#define ptregs_execve sys_execve28#define ptregs_execve sys_execve
29#define ptregs_iopl sys_iopl29#define ptregs_iopl sys_iopl
30#define ptregs_vm86old sys_vm86old30#define ptregs_vm86old sys_vm86old
31#define ptregs_clone sys_clone31#define ptregs_clone i386_clone
32#define ptregs_vm86 sys_vm8632#define ptregs_vm86 sys_vm86
33#define ptregs_sigaltstack sys_sigaltstack33#define ptregs_sigaltstack sys_sigaltstack
34#define ptregs_vfork sys_vfork34#define ptregs_vfork sys_vfork
arch/x86/um/syscalls_32.c+7−20
@@ -3,37 +3,24 @@ · 2 unmodified lines
3 * Licensed under the GPL3 * 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 the14 * 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 */
22long sys_clone(unsigned long clone_flags, unsigned long newsp,17long 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(&current->thread.regs.regs);
29
30 current->thread.forking = 1;
31 ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
32 child_tid);
33 current->thread.forking = 0;
34 return ret;
35}21}
36 22
23
37long sys_sigaction(int sig, const struct old_sigaction __user *act,24long sys_sigaction(int sig, const struct old_sigaction __user *act,
38 struct old_sigaction __user *oact)25 struct old_sigaction __user *oact)
39{26{
arch/x86/um/syscalls_64.c+3−20
@@ -5,12 +5,9 @@ · 4 unmodified lines
5 * Licensed under the GPL5 * 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
15long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)12long 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) · 62 unmodified lines
79 return arch_prctl(current, code, (unsigned long __user *) addr);76 return arch_prctl(current, code, (unsigned long __user *) addr);
80}77}
81 78
82long 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(&current->thread.regs.regs);
89 current->thread.forking = 1;
90 ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
91 child_tid);
92 current->thread.forking = 0;
93 return ret;
94}
95
96void arch_switch_to(struct task_struct *to)79void 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))