aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-26 19:59:16 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-11-28 22:36:46 -0500
commit415bfae9e9dbc2232f1797a3ac78a22049a75e06 (patch)
treed5cd2e445270a1ffc6f1f5a860d458cbf321066b /arch/parisc/kernel
parent92bbe6cdfdeeaf9ac2a240b1829bab219e7e91d0 (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.S38
-rw-r--r--arch/parisc/kernel/process.c49
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
1691ENTRY(sys_fork_wrapper) 1691 .macro fork_like name
1692ENTRY(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)
1699ENDPROC(sys_\name\()_wrapper)
1700 .endm
1697 1701
1698 LDREG PT_GR30(%r1),%r25 1702fork_like clone
1699 copy %r1,%r24 1703fork_like fork
1700 b sys_clone 1704fork_like vfork
1701 ldi SIGCHLD,%r26
1702ENDPROC(sys_fork_wrapper)
1703 1705
1704 /* Set the return value for the child */ 1706 /* Set the return value for the child */
1705ENTRY(child_return) 1707ENTRY(child_return)
@@ -1716,30 +1718,6 @@ finish_child_return:
1716 copy %r0,%r28 1718 copy %r0,%r28
1717ENDPROC(child_return) 1719ENDPROC(child_return)
1718 1720
1719
1720ENTRY(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
1728ENDPROC(sys_clone_wrapper)
1729
1730
1731ENTRY(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
1740ENDPROC(sys_vfork_wrapper)
1741
1742
1743ENTRY(sys_rt_sigreturn_wrapper) 1721ENTRY(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). */
207int
208sys_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
235int
236sys_vfork(struct pt_regs *regs)
237{
238 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
239}
240
241int 205int
242copy_thread(unsigned long clone_flags, unsigned long usp, 206copy_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;