diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 23:02:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 23:02:25 -0400 |
commit | 42859eea96ba6beabfb0369a1eeffa3c7d2bd9cb (patch) | |
tree | fa38aeda0d6e7a4c48a882b166b8643594a1ad50 /arch/s390/kernel | |
parent | f59b51fe3d3092c08d7d554ecb40db24011b2ebc (diff) | |
parent | f322220d6159455da2b5a8a596d802c8695fed30 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull generic execve() changes from Al Viro:
"This introduces the generic kernel_thread() and kernel_execve()
functions, and switches x86, arm, alpha, um and s390 over to them."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (26 commits)
s390: convert to generic kernel_execve()
s390: switch to generic kernel_thread()
s390: fold kernel_thread_helper() into ret_from_fork()
s390: fold execve_tail() into start_thread(), convert to generic sys_execve()
um: switch to generic kernel_thread()
x86, um/x86: switch to generic sys_execve and kernel_execve
x86: split ret_from_fork
alpha: introduce ret_from_kernel_execve(), switch to generic kernel_execve()
alpha: switch to generic kernel_thread()
alpha: switch to generic sys_execve()
arm: get rid of execve wrapper, switch to generic execve() implementation
arm: optimized current_pt_regs()
arm: introduce ret_from_kernel_execve(), switch to generic kernel_execve()
arm: split ret_from_fork, simplify kernel_thread() [based on patch by rmk]
generic sys_execve()
generic kernel_execve()
new helper: current_pt_regs()
preparation for generic kernel_thread()
um: kill thread->forking
um: let signal_delivered() do SIGTRAP on singlestepping into handler
...
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/compat_linux.c | 26 | ||||
-rw-r--r-- | arch/s390/kernel/compat_linux.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 51 | ||||
-rw-r--r-- | arch/s390/kernel/entry.h | 3 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 50 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 107 |
7 files changed, 75 insertions, 166 deletions
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 189963c90c6e..65cca95843e1 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -432,32 +432,6 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) | |||
432 | return ret; | 432 | return ret; |
433 | } | 433 | } |
434 | 434 | ||
435 | /* | ||
436 | * sys32_execve() executes a new program after the asm stub has set | ||
437 | * things up for us. This should basically do what I want it to. | ||
438 | */ | ||
439 | asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv, | ||
440 | compat_uptr_t __user *envp) | ||
441 | { | ||
442 | struct pt_regs *regs = task_pt_regs(current); | ||
443 | char *filename; | ||
444 | long rc; | ||
445 | |||
446 | filename = getname(name); | ||
447 | rc = PTR_ERR(filename); | ||
448 | if (IS_ERR(filename)) | ||
449 | return rc; | ||
450 | rc = compat_do_execve(filename, argv, envp, regs); | ||
451 | if (rc) | ||
452 | goto out; | ||
453 | current->thread.fp_regs.fpc=0; | ||
454 | asm volatile("sfpc %0,0" : : "d" (0)); | ||
455 | rc = regs->gprs[2]; | ||
456 | out: | ||
457 | putname(filename); | ||
458 | return rc; | ||
459 | } | ||
460 | |||
461 | asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, | 435 | asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, |
462 | size_t count, u32 poshi, u32 poslo) | 436 | size_t count, u32 poshi, u32 poslo) |
463 | { | 437 | { |
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 90887bd98cf0..d4d0239970ac 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h | |||
@@ -125,8 +125,6 @@ long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, | |||
125 | compat_sigset_t __user *oset, size_t sigsetsize); | 125 | compat_sigset_t __user *oset, size_t sigsetsize); |
126 | long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize); | 126 | long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize); |
127 | long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo); | 127 | long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo); |
128 | long sys32_execve(const char __user *name, compat_uptr_t __user *argv, | ||
129 | compat_uptr_t __user *envp); | ||
130 | long sys32_init_module(void __user *umod, unsigned long len, | 128 | long sys32_init_module(void __user *umod, unsigned long len, |
131 | const char __user *uargs); | 129 | const char __user *uargs); |
132 | long sys32_delete_module(const char __user *name_user, unsigned int flags); | 130 | long sys32_delete_module(const char __user *name_user, unsigned int flags); |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 3afba804fe97..ad79b846535c 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1576,7 +1576,7 @@ ENTRY(sys32_execve_wrapper) | |||
1576 | llgtr %r2,%r2 # char * | 1576 | llgtr %r2,%r2 # char * |
1577 | llgtr %r3,%r3 # compat_uptr_t * | 1577 | llgtr %r3,%r3 # compat_uptr_t * |
1578 | llgtr %r4,%r4 # compat_uptr_t * | 1578 | llgtr %r4,%r4 # compat_uptr_t * |
1579 | jg sys32_execve # branch to system call | 1579 | jg compat_sys_execve # branch to system call |
1580 | 1580 | ||
1581 | ENTRY(sys_fanotify_init_wrapper) | 1581 | ENTRY(sys_fanotify_init_wrapper) |
1582 | llgfr %r2,%r2 # unsigned int | 1582 | llgfr %r2,%r2 # unsigned int |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 870bad6d56fc..ef46f66bc0d6 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -331,45 +331,38 @@ ENTRY(ret_from_fork) | |||
331 | l %r12,__LC_THREAD_INFO | 331 | l %r12,__LC_THREAD_INFO |
332 | l %r13,__LC_SVC_NEW_PSW+4 | 332 | l %r13,__LC_SVC_NEW_PSW+4 |
333 | tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ? | 333 | tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ? |
334 | jo 0f | 334 | je 1f |
335 | st %r15,__PT_R15(%r11) # store stack pointer for new kthread | 335 | l %r1,BASED(.Lschedule_tail) |
336 | 0: l %r1,BASED(.Lschedule_tail) | ||
337 | basr %r14,%r1 # call schedule_tail | 336 | basr %r14,%r1 # call schedule_tail |
338 | TRACE_IRQS_ON | 337 | TRACE_IRQS_ON |
339 | ssm __LC_SVC_NEW_PSW # reenable interrupts | 338 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
340 | j sysc_tracenogo | 339 | j sysc_tracenogo |
341 | 340 | ||
341 | 1: # it's a kernel thread | ||
342 | st %r15,__PT_R15(%r11) # store stack pointer for new kthread | ||
343 | l %r1,BASED(.Lschedule_tail) | ||
344 | basr %r14,%r1 # call schedule_tail | ||
345 | TRACE_IRQS_ON | ||
346 | ssm __LC_SVC_NEW_PSW # reenable interrupts | ||
347 | lm %r9,%r11,__PT_R9(%r11) # load gprs | ||
348 | ENTRY(kernel_thread_starter) | ||
349 | la %r2,0(%r10) | ||
350 | basr %r14,%r9 | ||
351 | la %r2,0 | ||
352 | br %r11 # do_exit | ||
353 | |||
342 | # | 354 | # |
343 | # kernel_execve function needs to deal with pt_regs that is not | 355 | # kernel_execve function needs to deal with pt_regs that is not |
344 | # at the usual place | 356 | # at the usual place |
345 | # | 357 | # |
346 | ENTRY(kernel_execve) | 358 | ENTRY(ret_from_kernel_execve) |
347 | stm %r12,%r15,48(%r15) | 359 | ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts |
348 | lr %r14,%r15 | 360 | lr %r15,%r2 |
349 | l %r13,__LC_SVC_NEW_PSW+4 | 361 | lr %r11,%r2 |
350 | ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 362 | ahi %r15,-STACK_FRAME_OVERHEAD |
351 | st %r14,__SF_BACKCHAIN(%r15) | ||
352 | la %r12,STACK_FRAME_OVERHEAD(%r15) | ||
353 | xc 0(__PT_SIZE,%r12),0(%r12) | ||
354 | l %r1,BASED(.Ldo_execve) | ||
355 | lr %r5,%r12 | ||
356 | basr %r14,%r1 # call do_execve | ||
357 | ltr %r2,%r2 | ||
358 | je 0f | ||
359 | ahi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
360 | lm %r12,%r15,48(%r15) | ||
361 | br %r14 | ||
362 | # execve succeeded. | ||
363 | 0: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts | ||
364 | l %r15,__LC_KERNEL_STACK # load ksp | ||
365 | ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
366 | la %r11,STACK_FRAME_OVERHEAD(%r15) | ||
367 | mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs | ||
368 | l %r12,__LC_THREAD_INFO | ||
369 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 363 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
364 | l %r12,__LC_THREAD_INFO | ||
370 | ssm __LC_SVC_NEW_PSW # reenable interrupts | 365 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
371 | l %r1,BASED(.Lexecve_tail) | ||
372 | basr %r14,%r1 # call execve_tail | ||
373 | j sysc_return | 366 | j sysc_return |
374 | 367 | ||
375 | /* | 368 | /* |
@@ -931,8 +924,6 @@ cleanup_idle_wait: | |||
931 | .Ldo_signal: .long do_signal | 924 | .Ldo_signal: .long do_signal |
932 | .Ldo_notify_resume: .long do_notify_resume | 925 | .Ldo_notify_resume: .long do_notify_resume |
933 | .Ldo_per_trap: .long do_per_trap | 926 | .Ldo_per_trap: .long do_per_trap |
934 | .Ldo_execve: .long do_execve | ||
935 | .Lexecve_tail: .long execve_tail | ||
936 | .Ljump_table: .long pgm_check_table | 927 | .Ljump_table: .long pgm_check_table |
937 | .Lschedule: .long schedule | 928 | .Lschedule: .long schedule |
938 | #ifdef CONFIG_PREEMPT | 929 | #ifdef CONFIG_PREEMPT |
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index a5f4dc42a5db..d0d3f69a7346 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h | |||
@@ -58,9 +58,6 @@ long sys_fork(void); | |||
58 | long sys_clone(unsigned long newsp, unsigned long clone_flags, | 58 | long sys_clone(unsigned long newsp, unsigned long clone_flags, |
59 | int __user *parent_tidptr, int __user *child_tidptr); | 59 | int __user *parent_tidptr, int __user *child_tidptr); |
60 | long sys_vfork(void); | 60 | long sys_vfork(void); |
61 | void execve_tail(void); | ||
62 | long sys_execve(const char __user *name, const char __user *const __user *argv, | ||
63 | const char __user *const __user *envp); | ||
64 | long sys_sigsuspend(int history0, int history1, old_sigset_t mask); | 61 | long sys_sigsuspend(int history0, int history1, old_sigset_t mask); |
65 | long sys_sigaction(int sig, const struct old_sigaction __user *act, | 62 | long sys_sigaction(int sig, const struct old_sigaction __user *act, |
66 | struct old_sigaction __user *oact); | 63 | struct old_sigaction __user *oact); |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 7549985402f7..f9761f806c9e 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -353,41 +353,31 @@ ENTRY(ret_from_fork) | |||
353 | la %r11,STACK_FRAME_OVERHEAD(%r15) | 353 | la %r11,STACK_FRAME_OVERHEAD(%r15) |
354 | lg %r12,__LC_THREAD_INFO | 354 | lg %r12,__LC_THREAD_INFO |
355 | tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ? | 355 | tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ? |
356 | jo 0f | 356 | je 1f |
357 | stg %r15,__PT_R15(%r11) # store stack pointer for new kthread | 357 | brasl %r14,schedule_tail |
358 | 0: brasl %r14,schedule_tail | ||
359 | TRACE_IRQS_ON | 358 | TRACE_IRQS_ON |
360 | ssm __LC_SVC_NEW_PSW # reenable interrupts | 359 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
361 | j sysc_tracenogo | 360 | j sysc_tracenogo |
362 | 361 | 1: # it's a kernel thread | |
363 | # | 362 | stg %r15,__PT_R15(%r11) # store stack pointer for new kthread |
364 | # kernel_execve function needs to deal with pt_regs that is not | 363 | brasl %r14,schedule_tail |
365 | # at the usual place | 364 | TRACE_IRQS_ON |
366 | # | 365 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
367 | ENTRY(kernel_execve) | 366 | lmg %r9,%r11,__PT_R9(%r11) # load gprs |
368 | stmg %r12,%r15,96(%r15) | 367 | ENTRY(kernel_thread_starter) |
369 | lgr %r14,%r15 | 368 | la %r2,0(%r10) |
370 | aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 369 | basr %r14,%r9 |
371 | stg %r14,__SF_BACKCHAIN(%r15) | 370 | la %r2,0 |
372 | la %r12,STACK_FRAME_OVERHEAD(%r15) | 371 | br %r11 # do_exit |
373 | xc 0(__PT_SIZE,%r12),0(%r12) | 372 | |
374 | lgr %r5,%r12 | 373 | ENTRY(ret_from_kernel_execve) |
375 | brasl %r14,do_execve | 374 | ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts |
376 | ltgfr %r2,%r2 | 375 | lgr %r15,%r2 |
377 | je 0f | 376 | lgr %r11,%r2 |
378 | aghi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE) | 377 | aghi %r15,-STACK_FRAME_OVERHEAD |
379 | lmg %r12,%r15,96(%r15) | ||
380 | br %r14 | ||
381 | # execve succeeded. | ||
382 | 0: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts | ||
383 | lg %r15,__LC_KERNEL_STACK # load ksp | ||
384 | aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
385 | la %r11,STACK_FRAME_OVERHEAD(%r15) | ||
386 | mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs | ||
387 | lg %r12,__LC_THREAD_INFO | ||
388 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 378 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
379 | lg %r12,__LC_THREAD_INFO | ||
389 | ssm __LC_SVC_NEW_PSW # reenable interrupts | 380 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
390 | brasl %r14,execve_tail | ||
391 | j sysc_return | 381 | j sysc_return |
392 | 382 | ||
393 | /* | 383 | /* |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 5024be27df44..cd31ad457a9b 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -100,35 +100,6 @@ void cpu_idle(void) | |||
100 | 100 | ||
101 | extern void __kprobes kernel_thread_starter(void); | 101 | extern void __kprobes kernel_thread_starter(void); |
102 | 102 | ||
103 | asm( | ||
104 | ".section .kprobes.text, \"ax\"\n" | ||
105 | ".global kernel_thread_starter\n" | ||
106 | "kernel_thread_starter:\n" | ||
107 | " la 2,0(10)\n" | ||
108 | " basr 14,9\n" | ||
109 | " la 2,0\n" | ||
110 | " br 11\n" | ||
111 | ".previous\n"); | ||
112 | |||
113 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
114 | { | ||
115 | struct pt_regs regs; | ||
116 | |||
117 | memset(®s, 0, sizeof(regs)); | ||
118 | regs.psw.mask = psw_kernel_bits | | ||
119 | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; | ||
120 | regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE; | ||
121 | regs.gprs[9] = (unsigned long) fn; | ||
122 | regs.gprs[10] = (unsigned long) arg; | ||
123 | regs.gprs[11] = (unsigned long) do_exit; | ||
124 | regs.orig_gpr2 = -1; | ||
125 | |||
126 | /* Ok, create the new process.. */ | ||
127 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, | ||
128 | 0, ®s, 0, NULL, NULL); | ||
129 | } | ||
130 | EXPORT_SYMBOL(kernel_thread); | ||
131 | |||
132 | /* | 103 | /* |
133 | * Free current thread data structures etc.. | 104 | * Free current thread data structures etc.. |
134 | */ | 105 | */ |
@@ -146,7 +117,7 @@ void release_thread(struct task_struct *dead_task) | |||
146 | } | 117 | } |
147 | 118 | ||
148 | int copy_thread(unsigned long clone_flags, unsigned long new_stackp, | 119 | int copy_thread(unsigned long clone_flags, unsigned long new_stackp, |
149 | unsigned long unused, | 120 | unsigned long arg, |
150 | struct task_struct *p, struct pt_regs *regs) | 121 | struct task_struct *p, struct pt_regs *regs) |
151 | { | 122 | { |
152 | struct thread_info *ti; | 123 | struct thread_info *ti; |
@@ -158,20 +129,44 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, | |||
158 | 129 | ||
159 | frame = container_of(task_pt_regs(p), struct fake_frame, childregs); | 130 | frame = container_of(task_pt_regs(p), struct fake_frame, childregs); |
160 | p->thread.ksp = (unsigned long) frame; | 131 | p->thread.ksp = (unsigned long) frame; |
161 | /* Store access registers to kernel stack of new process. */ | 132 | /* Save access registers to new thread structure. */ |
162 | frame->childregs = *regs; | 133 | save_access_regs(&p->thread.acrs[0]); |
163 | frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ | 134 | /* start new process with ar4 pointing to the correct address space */ |
164 | frame->childregs.gprs[15] = new_stackp; | 135 | p->thread.mm_segment = get_fs(); |
165 | frame->sf.back_chain = 0; | 136 | /* Don't copy debug registers */ |
137 | memset(&p->thread.per_user, 0, sizeof(p->thread.per_user)); | ||
138 | memset(&p->thread.per_event, 0, sizeof(p->thread.per_event)); | ||
139 | clear_tsk_thread_flag(p, TIF_SINGLE_STEP); | ||
140 | clear_tsk_thread_flag(p, TIF_PER_TRAP); | ||
141 | /* Initialize per thread user and system timer values */ | ||
142 | ti = task_thread_info(p); | ||
143 | ti->user_timer = 0; | ||
144 | ti->system_timer = 0; | ||
166 | 145 | ||
146 | frame->sf.back_chain = 0; | ||
167 | /* new return point is ret_from_fork */ | 147 | /* new return point is ret_from_fork */ |
168 | frame->sf.gprs[8] = (unsigned long) ret_from_fork; | 148 | frame->sf.gprs[8] = (unsigned long) ret_from_fork; |
169 | |||
170 | /* fake return stack for resume(), don't go back to schedule */ | 149 | /* fake return stack for resume(), don't go back to schedule */ |
171 | frame->sf.gprs[9] = (unsigned long) frame; | 150 | frame->sf.gprs[9] = (unsigned long) frame; |
172 | 151 | ||
173 | /* Save access registers to new thread structure. */ | 152 | /* Store access registers to kernel stack of new process. */ |
174 | save_access_regs(&p->thread.acrs[0]); | 153 | if (unlikely(!regs)) { |
154 | /* kernel thread */ | ||
155 | memset(&frame->childregs, 0, sizeof(struct pt_regs)); | ||
156 | frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | | ||
157 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; | ||
158 | frame->childregs.psw.addr = PSW_ADDR_AMODE | | ||
159 | (unsigned long) kernel_thread_starter; | ||
160 | frame->childregs.gprs[9] = new_stackp; /* function */ | ||
161 | frame->childregs.gprs[10] = arg; | ||
162 | frame->childregs.gprs[11] = (unsigned long) do_exit; | ||
163 | frame->childregs.orig_gpr2 = -1; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | frame->childregs = *regs; | ||
168 | frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ | ||
169 | frame->childregs.gprs[15] = new_stackp; | ||
175 | 170 | ||
176 | /* Don't copy runtime instrumentation info */ | 171 | /* Don't copy runtime instrumentation info */ |
177 | p->thread.ri_cb = NULL; | 172 | p->thread.ri_cb = NULL; |
@@ -202,17 +197,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, | |||
202 | } | 197 | } |
203 | } | 198 | } |
204 | #endif /* CONFIG_64BIT */ | 199 | #endif /* CONFIG_64BIT */ |
205 | /* start new process with ar4 pointing to the correct address space */ | ||
206 | p->thread.mm_segment = get_fs(); | ||
207 | /* Don't copy debug registers */ | ||
208 | memset(&p->thread.per_user, 0, sizeof(p->thread.per_user)); | ||
209 | memset(&p->thread.per_event, 0, sizeof(p->thread.per_event)); | ||
210 | clear_tsk_thread_flag(p, TIF_SINGLE_STEP); | ||
211 | clear_tsk_thread_flag(p, TIF_PER_TRAP); | ||
212 | /* Initialize per thread user and system timer values */ | ||
213 | ti = task_thread_info(p); | ||
214 | ti->user_timer = 0; | ||
215 | ti->system_timer = 0; | ||
216 | return 0; | 200 | return 0; |
217 | } | 201 | } |
218 | 202 | ||
@@ -258,31 +242,6 @@ asmlinkage void execve_tail(void) | |||
258 | } | 242 | } |
259 | 243 | ||
260 | /* | 244 | /* |
261 | * sys_execve() executes a new program. | ||
262 | */ | ||
263 | SYSCALL_DEFINE3(execve, const char __user *, name, | ||
264 | const char __user *const __user *, argv, | ||
265 | const char __user *const __user *, envp) | ||
266 | { | ||
267 | struct pt_regs *regs = task_pt_regs(current); | ||
268 | char *filename; | ||
269 | long rc; | ||
270 | |||
271 | filename = getname(name); | ||
272 | rc = PTR_ERR(filename); | ||
273 | if (IS_ERR(filename)) | ||
274 | return rc; | ||
275 | rc = do_execve(filename, argv, envp, regs); | ||
276 | if (rc) | ||
277 | goto out; | ||
278 | execve_tail(); | ||
279 | rc = regs->gprs[2]; | ||
280 | out: | ||
281 | putname(filename); | ||
282 | return rc; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * fill in the FPU structure for a core dump. | 245 | * fill in the FPU structure for a core dump. |
287 | */ | 246 | */ |
288 | int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) | 247 | int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) |