diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-26 19:59:16 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-28 22:36:46 -0500 |
commit | 415bfae9e9dbc2232f1797a3ac78a22049a75e06 (patch) | |
tree | d5cd2e445270a1ffc6f1f5a860d458cbf321066b /arch/parisc/kernel | |
parent | 92bbe6cdfdeeaf9ac2a240b1829bab219e7e91d0 (diff) |
parisc: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r-- | arch/parisc/kernel/entry.S | 38 | ||||
-rw-r--r-- | arch/parisc/kernel/process.c | 49 |
2 files changed, 18 insertions, 69 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index c9a9abd4bc58..bfb44247d7a7 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -1688,18 +1688,20 @@ dtlb_fault: | |||
1688 | LDREG PT_GR18(\regs),%r18 | 1688 | LDREG PT_GR18(\regs),%r18 |
1689 | .endm | 1689 | .endm |
1690 | 1690 | ||
1691 | ENTRY(sys_fork_wrapper) | 1691 | .macro fork_like name |
1692 | ENTRY(sys_\name\()_wrapper) | ||
1692 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 | 1693 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 |
1693 | ldo TASK_REGS(%r1),%r1 | 1694 | ldo TASK_REGS(%r1),%r1 |
1694 | reg_save %r1 | 1695 | reg_save %r1 |
1695 | mfctl %cr27, %r28 | 1696 | mfctl %cr27, %r28 |
1697 | b sys_\name | ||
1696 | STREG %r28, PT_CR27(%r1) | 1698 | STREG %r28, PT_CR27(%r1) |
1699 | ENDPROC(sys_\name\()_wrapper) | ||
1700 | .endm | ||
1697 | 1701 | ||
1698 | LDREG PT_GR30(%r1),%r25 | 1702 | fork_like clone |
1699 | copy %r1,%r24 | 1703 | fork_like fork |
1700 | b sys_clone | 1704 | fork_like vfork |
1701 | ldi SIGCHLD,%r26 | ||
1702 | ENDPROC(sys_fork_wrapper) | ||
1703 | 1705 | ||
1704 | /* Set the return value for the child */ | 1706 | /* Set the return value for the child */ |
1705 | ENTRY(child_return) | 1707 | ENTRY(child_return) |
@@ -1716,30 +1718,6 @@ finish_child_return: | |||
1716 | copy %r0,%r28 | 1718 | copy %r0,%r28 |
1717 | ENDPROC(child_return) | 1719 | ENDPROC(child_return) |
1718 | 1720 | ||
1719 | |||
1720 | ENTRY(sys_clone_wrapper) | ||
1721 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 | ||
1722 | ldo TASK_REGS(%r1),%r1 /* get pt regs */ | ||
1723 | reg_save %r1 | ||
1724 | mfctl %cr27, %r28 | ||
1725 | STREG %r28, PT_CR27(%r1) | ||
1726 | b sys_clone | ||
1727 | copy %r1,%r24 | ||
1728 | ENDPROC(sys_clone_wrapper) | ||
1729 | |||
1730 | |||
1731 | ENTRY(sys_vfork_wrapper) | ||
1732 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 | ||
1733 | ldo TASK_REGS(%r1),%r1 /* get pt regs */ | ||
1734 | reg_save %r1 | ||
1735 | mfctl %cr27, %r28 | ||
1736 | STREG %r28, PT_CR27(%r1) | ||
1737 | |||
1738 | b sys_vfork | ||
1739 | copy %r1,%r26 | ||
1740 | ENDPROC(sys_vfork_wrapper) | ||
1741 | |||
1742 | |||
1743 | ENTRY(sys_rt_sigreturn_wrapper) | 1721 | ENTRY(sys_rt_sigreturn_wrapper) |
1744 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 | 1722 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 |
1745 | ldo TASK_REGS(%r26),%r26 /* get pt regs */ | 1723 | ldo TASK_REGS(%r26),%r26 /* get pt regs */ |
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 38db36f64307..9753ecf49a06 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c | |||
@@ -202,46 +202,10 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) | |||
202 | return 1; | 202 | return 1; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* Note that "fork()" is implemented in terms of clone, with | ||
206 | parameters (SIGCHLD, regs->gr[30], regs). */ | ||
207 | int | ||
208 | sys_clone(unsigned long clone_flags, unsigned long usp, | ||
209 | struct pt_regs *regs) | ||
210 | { | ||
211 | /* Arugments from userspace are: | ||
212 | r26 = Clone flags. | ||
213 | r25 = Child stack. | ||
214 | r24 = parent_tidptr. | ||
215 | r23 = Is the TLS storage descriptor | ||
216 | r22 = child_tidptr | ||
217 | |||
218 | However, these last 3 args are only examined | ||
219 | if the proper flags are set. */ | ||
220 | int __user *parent_tidptr = (int __user *)regs->gr[24]; | ||
221 | int __user *child_tidptr = (int __user *)regs->gr[22]; | ||
222 | |||
223 | /* usp must be word aligned. This also prevents users from | ||
224 | * passing in the value 1 (which is the signal for a special | ||
225 | * return for a kernel thread) */ | ||
226 | usp = ALIGN(usp, 4); | ||
227 | |||
228 | /* A zero value for usp means use the current stack */ | ||
229 | if (usp == 0) | ||
230 | usp = regs->gr[30]; | ||
231 | |||
232 | return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr); | ||
233 | } | ||
234 | |||
235 | int | ||
236 | sys_vfork(struct pt_regs *regs) | ||
237 | { | ||
238 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL); | ||
239 | } | ||
240 | |||
241 | int | 205 | int |
242 | copy_thread(unsigned long clone_flags, unsigned long usp, | 206 | copy_thread(unsigned long clone_flags, unsigned long usp, |
243 | unsigned long arg, | 207 | unsigned long arg, |
244 | struct task_struct *p, struct pt_regs *pregs) | 208 | struct task_struct *p, struct pt_regs *unused) |
245 | { | 209 | { |
246 | struct pt_regs * cregs = &(p->thread.regs); | 210 | struct pt_regs * cregs = &(p->thread.regs); |
247 | void *stack = task_stack_page(p); | 211 | void *stack = task_stack_page(p); |
@@ -278,7 +242,14 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
278 | cregs->gr[25] = arg; | 242 | cregs->gr[25] = arg; |
279 | } else { | 243 | } else { |
280 | /* user thread */ | 244 | /* user thread */ |
281 | cregs->gr[30] = usp; | 245 | /* usp must be word aligned. This also prevents users from |
246 | * passing in the value 1 (which is the signal for a special | ||
247 | * return for a kernel thread) */ | ||
248 | if (usp) { | ||
249 | usp = ALIGN(usp, 4); | ||
250 | if (likely(usp)) | ||
251 | cregs->gr[30] = usp; | ||
252 | } | ||
282 | cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; | 253 | cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; |
283 | if (personality(p->personality) == PER_HPUX) { | 254 | if (personality(p->personality) == PER_HPUX) { |
284 | #ifdef CONFIG_HPUX | 255 | #ifdef CONFIG_HPUX |
@@ -291,7 +262,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
291 | } | 262 | } |
292 | /* Setup thread TLS area from the 4th parameter in clone */ | 263 | /* Setup thread TLS area from the 4th parameter in clone */ |
293 | if (clone_flags & CLONE_SETTLS) | 264 | if (clone_flags & CLONE_SETTLS) |
294 | cregs->cr27 = pregs->gr[23]; | 265 | cregs->cr27 = cregs->gr[23]; |
295 | } | 266 | } |
296 | 267 | ||
297 | return 0; | 268 | return 0; |