diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-08-17 10:32:20 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-08-17 10:32:20 +0000 |
commit | d86a6c16672c6fd6de49e6c04095bbe180db8edf (patch) | |
tree | d4538cad037bcb5ad1572a3d144628a50e829859 /sys | |
parent | 63b7a98cc57e3a3fbf4e70bcd27a4eb65721c359 (diff) |
New cpu_fork API to take a stack in which you point the child's stackpointer
to, at the bottom or the top, depending on your architecture's stack growth
direction. This is in preparation for Linux' clone(2) emulation.
port maintainers, please check that I did the work right.
Diffstat (limited to 'sys')
27 files changed, 240 insertions, 66 deletions
diff --git a/sys/arch/alpha/alpha/vm_machdep.c b/sys/arch/alpha/alpha/vm_machdep.c index 2d79c11bd89..a5880097ec8 100644 --- a/sys/arch/alpha/alpha/vm_machdep.c +++ b/sys/arch/alpha/alpha/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.9 1999/01/10 13:34:17 niklas Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.10 1999/08/17 10:32:16 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.21 1996/11/13 21:13:15 cgd Exp $ */ /* @@ -133,8 +133,10 @@ cpu_exit(p) * the frame pointers on the stack after copying. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { struct user *up = p2->p_addr; pt_entry_t *ptep; @@ -229,6 +231,12 @@ printf("FORK CHILD: pc = %p, ra = %p\n", p2tf->tf_regs[FRAME_PC], p2tf->tf_regs[ p2tf->tf_regs[FRAME_A4] = 1; /* is child */ /* + * If specificed, give the child a different stack. + */ + if (stack != NULL) + p2tf->tf_regs[FRAME_SP] = (u_long)stack + stacksize; + + /* * Arrange for continuation at child_return(), which * will return to exception_return(). Note that the child * process doesn't stay in the kernel for long! diff --git a/sys/arch/amiga/amiga/vm_machdep.c b/sys/arch/amiga/amiga/vm_machdep.c index 2a682cc8a23..d941aea6697 100644 --- a/sys/arch/amiga/amiga/vm_machdep.c +++ b/sys/arch/amiga/amiga/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.9 1999/01/10 13:34:17 niklas Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.10 1999/08/17 10:32:16 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.30 1997/05/19 10:14:50 veego Exp $ */ /* @@ -74,8 +74,10 @@ void child_return __P((struct proc *, struct frame)); * the frame pointers on the stack after copying. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *pcb = &p2->p_addr->u_pcb; register struct trapframe *tf; @@ -97,6 +99,13 @@ cpu_fork(p1, p2) tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1; p2->p_md.md_regs = (int *)tf; *tf = *(struct trapframe *)p1->p_md.md_regs; + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->tf_regs[15] = (u_int)stack + stacksize; + sf = (struct switchframe *)tf - 1; sf->sf_pc = (u_int)proc_trampoline; pcb->pcb_regs[6] = (int)child_return; /* A2 */ diff --git a/sys/arch/arm32/arm32/vm_machdep.c b/sys/arch/arm32/arm32/vm_machdep.c index 46c6517715d..7339a636b17 100644 --- a/sys/arch/arm32/arm32/vm_machdep.c +++ b/sys/arch/arm32/arm32/vm_machdep.c @@ -103,9 +103,11 @@ extern void child_return __P(()); */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) struct proc *p1; struct proc *p2; + void *stack; + size_t stacksize; { struct user *up = p2->p_addr; struct pcb *pcb = (struct pcb *)&p2->p_addr->u_pcb; @@ -238,6 +240,13 @@ cpu_fork(p1, p2) p2->p_md.md_regs = tf = (struct trapframe *)pcb->pcb_sp - 1; *tf = *p1->p_md.md_regs; + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->tf_usr_sp = (u_int)stack + stacksize; + sf = (struct switchframe *)tf - 1; sf->sf_spl = SPL_0; sf->sf_r4 = (u_int)child_return; diff --git a/sys/arch/atari/atari/vm_machdep.c b/sys/arch/atari/atari/vm_machdep.c index 8799926f17d..1eb03c4dd00 100644 --- a/sys/arch/atari/atari/vm_machdep.c +++ b/sys/arch/atari/atari/vm_machdep.c @@ -69,8 +69,10 @@ * the frame pointers on the stack after copying. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *pcb = &p2->p_addr->u_pcb; register struct trapframe *tf; @@ -91,6 +93,13 @@ cpu_fork(p1, p2) tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1; p2->p_md.md_regs = (int *)tf; *tf = *(struct trapframe *)p1->p_md.md_regs; + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->tf_regs[15] = (u_int)stack + stacksize; + sf = (struct switchframe *)tf - 1; sf->sf_pc = (u_int)proc_trampoline; pcb->pcb_regs[6] = (int)child_return; /* A2 */ diff --git a/sys/arch/hp300/hp300/vm_machdep.c b/sys/arch/hp300/hp300/vm_machdep.c index c9eeb9ab78f..03ff82cbf4f 100644 --- a/sys/arch/hp300/hp300/vm_machdep.c +++ b/sys/arch/hp300/hp300/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.12 1999/01/10 13:34:17 niklas Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.13 1999/08/17 10:32:16 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.37 1997/05/26 00:27:43 thorpej Exp $ */ /* @@ -71,8 +71,10 @@ * the frame pointers on the stack after copying. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) struct proc *p1, *p2; + void *stack; + size_t stacksize; { void child_return __P((struct proc *, struct frame)); struct pcb *pcb = &p2->p_addr->u_pcb; @@ -95,6 +97,13 @@ cpu_fork(p1, p2) tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1; p2->p_md.md_regs = (int *)tf; *tf = *(struct trapframe *)p1->p_md.md_regs; + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->tf_regs[15] = (u_int)stack + stacksize; + sf = (struct switchframe *)tf - 1; sf->sf_pc = (u_int)proc_trampoline; pcb->pcb_regs[6] = (int)child_return; /* A2 */ diff --git a/sys/arch/hppa/hppa/vm_machdep.c b/sys/arch/hppa/hppa/vm_machdep.c index 10d330ce81f..f96dea277f5 100644 --- a/sys/arch/hppa/hppa/vm_machdep.c +++ b/sys/arch/hppa/hppa/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.6 1999/06/12 18:13:18 mickey Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.7 1999/08/17 10:32:16 niklas Exp $ */ #include <sys/param.h> #include <sys/systm.h> @@ -103,8 +103,10 @@ cpu_swapout(p) } void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *pcbp; register struct trapframe *tf; @@ -123,11 +125,18 @@ cpu_fork(p1, p2) p2->p_md.md_regs = tf = &pcbp->pcb_tf; sp = (struct hppa_frame *)((register_t)p2->p_addr + round_page(sizeof(struct user))); + /* setup initial stack frame */ bzero(sp, sizeof(struct hppa_frame)); tf->tf_sp = (register_t)(sp + 1); /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->tf_sp = (register_t)stack; + + /* * everybody recomends to note here the inline version of * the cpu_set_kpc(), so note it ! */ diff --git a/sys/arch/i386/i386/vm_machdep.c b/sys/arch/i386/i386/vm_machdep.c index 76ef0ac24f3..78c3e5fa531 100644 --- a/sys/arch/i386/i386/vm_machdep.c +++ b/sys/arch/i386/i386/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.16 1999/02/26 10:37:51 art Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.17 1999/08/17 10:32:16 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.61 1996/05/03 19:42:35 christos Exp $ */ /*- @@ -86,8 +86,10 @@ void setredzone __P((u_short *, caddr_t)); * the frame pointers on the stack after copying. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *pcb = &p2->p_addr->u_pcb; register struct trapframe *tf; @@ -149,6 +151,13 @@ cpu_fork(p1, p2) */ p2->p_md.md_regs = tf = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1; *tf = *p1->p_md.md_regs; + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->tf_esp = (u_int)stack + stacksize; + sf = (struct switchframe *)tf - 1; sf->sf_ppl = 0; sf->sf_esi = (int)child_return; diff --git a/sys/arch/kbus/kbus/vm_machdep.c b/sys/arch/kbus/kbus/vm_machdep.c index 18a8f77c4a0..445f159f2e5 100644 --- a/sys/arch/kbus/kbus/vm_machdep.c +++ b/sys/arch/kbus/kbus/vm_machdep.c @@ -67,8 +67,10 @@ * address in each process; in the future we will probably relocate * the frame pointers on the stack after copying. */ -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { struct user *up = p2->p_addr; int foo, offset, addr, i; @@ -256,8 +258,10 @@ vunmapbuf(bp, sz) * the first element in struct user. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *opcb = &p1->p_addr->u_pcb; register struct pcb *npcb = &p2->p_addr->u_pcb; @@ -314,6 +318,12 @@ cpu_fork(p1, p2) /* Copy parent's trapframe */ *tf2 = *(struct trapframe *)((int)opcb + USPACE - sizeof(*tf2)); + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf2->tf_out[6] = (u_int)stack + stacksize; + /* Duplicate efforts of syscall(), but slightly differently */ if (tf2->tf_global[1] & SYSCALL_G2RFLAG) { /* jmp %g2 (or %g7, deprecated) on success */ diff --git a/sys/arch/mac68k/mac68k/vm_machdep.c b/sys/arch/mac68k/mac68k/vm_machdep.c index 3bb8b5a3b9e..b4ac53a2855 100644 --- a/sys/arch/mac68k/mac68k/vm_machdep.c +++ b/sys/arch/mac68k/mac68k/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.11 1999/01/10 13:34:18 niklas Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.12 1999/08/17 10:32:17 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.21 1996/09/16 18:00:31 scottr Exp $ */ /* @@ -75,8 +75,10 @@ void savectx __P((struct pcb *)); * the frame pointers on the stack after copying. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *pcb = &p2->p_addr->u_pcb; register struct trapframe *tf; @@ -97,8 +99,14 @@ cpu_fork(p1, p2) */ tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) -1; p2->p_md.md_regs = (int *)tf; - *tf = *(struct trapframe *)p1->p_md.md_regs; + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->tf_regs[15] = (u_int)stack + stacksize; + sf = (struct switchframe *)tf - 1; sf->sf_pc = (u_int)proc_trampoline; diff --git a/sys/arch/mips/mips/vm_machdep.c b/sys/arch/mips/mips/vm_machdep.c index 642fc7c3cb6..8f8aaba4e5f 100644 --- a/sys/arch/mips/mips/vm_machdep.c +++ b/sys/arch/mips/mips/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.5 1998/10/15 21:30:15 imp Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.6 1999/08/17 10:32:17 niklas Exp $ */ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 @@ -74,8 +74,10 @@ int vm_map_find_U __P((vm_map_t, vm_object_t, vm_offset_t, vm_offset_t *, * the frame pointers on the stack after copying. */ int -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { struct user *up = p2->p_addr; pt_entry_t *pte; @@ -113,6 +115,14 @@ cpu_fork(p1, p2) /* cache segtab for ULTBMiss() */ p2->p_addr->u_pcb.pcb_segtab = (void *)p2->p_vmspace->vm_pmap.pm_segtab; +#ifdef notyet + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + /* XXX How??? */; +#endif + /* * Arrange for a non-local goto when the new process * is started, to resume here, returning nonzero from setjmp. diff --git a/sys/arch/mvme68k/mvme68k/vm_machdep.c b/sys/arch/mvme68k/mvme68k/vm_machdep.c index 49b501eebde..d15397fb852 100644 --- a/sys/arch/mvme68k/mvme68k/vm_machdep.c +++ b/sys/arch/mvme68k/mvme68k/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.11 1999/06/06 15:38:34 deraadt Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.12 1999/08/17 10:32:17 niklas Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -67,8 +67,10 @@ * the frame pointers on the stack after copying. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *pcb = &p2->p_addr->u_pcb; register struct trapframe *tf; @@ -89,6 +91,13 @@ cpu_fork(p1, p2) tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1; p2->p_md.md_regs = (int *)tf; *tf = *(struct trapframe *)p1->p_md.md_regs; + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->tf_regs[15] = (u_int)stack + stacksize; + sf = (struct switchframe *)tf - 1; sf->sf_pc = (u_int)proc_trampoline; pcb->pcb_regs[6] = (int)child_return; /* A2 */ diff --git a/sys/arch/mvme88k/mvme88k/vm_machdep.c b/sys/arch/mvme88k/mvme88k/vm_machdep.c index d9f5f05d898..79f2b3ed93f 100644 --- a/sys/arch/mvme88k/mvme88k/vm_machdep.c +++ b/sys/arch/mvme88k/mvme88k/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.8 1999/05/29 04:41:47 smurph Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.9 1999/08/17 10:32:17 niklas Exp $ */ /* * Copyright (c) 1998 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -42,7 +42,7 @@ * from: Utah $Hdr: vm_machdep.c 1.21 91/04/06$ * from: @(#)vm_machdep.c 7.10 (Berkeley) 5/7/91 * vm_machdep.c,v 1.3 1993/07/07 07:09:32 cgd Exp - * $Id: vm_machdep.c,v 1.8 1999/05/29 04:41:47 smurph Exp $ + * $Id: vm_machdep.c,v 1.9 1999/08/17 10:32:17 niklas Exp $ */ #include <sys/param.h> @@ -79,7 +79,7 @@ int #else void #endif -cpu_fork(struct proc *p1, struct proc *p2) +cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize) { struct switchframe *p2sf; int off, ssz; @@ -112,6 +112,12 @@ cpu_fork(struct proc *p1, struct proc *p2) p2sf->sf_proc = p2; p2->p_addr->u_pcb.kernel_state.pcb_sp = (u_int)p2sf; + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + USER_REGS(p2)->pcb_sp = (u_int)stack + stacksize; + ksfp = (struct ksigframe *)p2->p_addr->u_pcb.kernel_state.pcb_sp - 1; ksfp->func = child_return; diff --git a/sys/arch/pc532/pc532/vm_machdep.c b/sys/arch/pc532/pc532/vm_machdep.c index 657b3e8270e..59d9d57fb8a 100644 --- a/sys/arch/pc532/pc532/vm_machdep.c +++ b/sys/arch/pc532/pc532/vm_machdep.c @@ -64,8 +64,10 @@ * address in each process; in the future we will probably relocate * the frame pointers on the stack after copying. */ -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { struct user *up = p2->p_addr; int foo, offset, addr, i; @@ -96,6 +98,8 @@ cpu_fork(p1, p2) /* * Low_level_fork returns twice! First with a 0 in the * parent space and Second with a 1 in the child. + * XXX the child should use stack, stack+stacksize as + * the stack if stack is not NULL. */ return (low_level_fork(up)); diff --git a/sys/arch/pmax/pmax/vm_machdep.c b/sys/arch/pmax/pmax/vm_machdep.c index e3a8162c9e6..421efb319ca 100644 --- a/sys/arch/pmax/pmax/vm_machdep.c +++ b/sys/arch/pmax/pmax/vm_machdep.c @@ -79,8 +79,10 @@ extern vm_offset_t kvtophys __P((vm_offset_t kva)); /* XXX */ * the frame pointers on the stack after copying. */ int -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct user *up = p2->p_addr; register pt_entry_t *pte; @@ -118,6 +120,14 @@ cpu_fork(p1, p2) /* cache segtab for ULTBMiss() */ p2->p_addr->u_pcb.pcb_segtab = (void *)p2->p_vmspace->vm_map.pmap->pm_segtab; +#ifdef notyet + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + /* XXX How??? */; +#endif + /* * Arrange for a non-local goto when the new process * is started, to resume here, returning nonzero from setjmp. diff --git a/sys/arch/powerpc/powerpc/vm_machdep.c b/sys/arch/powerpc/powerpc/vm_machdep.c index d43e13da067..9a25dae28ea 100644 --- a/sys/arch/powerpc/powerpc/vm_machdep.c +++ b/sys/arch/powerpc/powerpc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.6 1999/01/23 19:41:33 rahnds Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.7 1999/08/17 10:32:17 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.1 1996/09/30 16:34:57 ws Exp $ */ /* @@ -47,8 +47,10 @@ * Finish a fork operation, with process p2 nearly set up. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) struct proc *p1, *p2; + void *stack; + size_t stacksize; { struct trapframe *tf; struct callframe *cf; @@ -71,6 +73,13 @@ cpu_fork(p1, p2) stktop1 = (caddr_t)trapframe(p1); stktop2 = (caddr_t)trapframe(p2); bcopy(stktop1, stktop2, sizeof(struct trapframe)); + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->fixreg[1] = (register_t)stack + stacksize; + stktop2 = (caddr_t)((u_long)stktop2 & ~15); /* Align stack pointer */ /* diff --git a/sys/arch/sparc/sparc/vm_machdep.c b/sys/arch/sparc/sparc/vm_machdep.c index 4093ab1a2a5..19be99b222b 100644 --- a/sys/arch/sparc/sparc/vm_machdep.c +++ b/sys/arch/sparc/sparc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.9 1999/07/09 21:30:03 art Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.10 1999/08/17 10:32:18 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.30 1997/03/10 23:55:40 pk Exp $ */ /* @@ -359,8 +359,10 @@ vunmapbuf(bp, sz) * the first element in struct user. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *opcb = &p1->p_addr->u_pcb; register struct pcb *npcb = &p2->p_addr->u_pcb; @@ -409,6 +411,12 @@ cpu_fork(p1, p2) /* Copy parent's trapframe */ *tf2 = *(struct trapframe *)((int)opcb + USPACE - sizeof(*tf2)); + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf2->tf_out[6] = (u_int)stack + stacksize; + /* Duplicate efforts of syscall(), but slightly differently */ if (tf2->tf_global[1] & SYSCALL_G2RFLAG) { /* jmp %g2 (or %g7, deprecated) on success */ diff --git a/sys/arch/sun3/sun3/vm_machdep.c b/sys/arch/sun3/sun3/vm_machdep.c index 168d29b530d..983724699ee 100644 --- a/sys/arch/sun3/sun3/vm_machdep.c +++ b/sys/arch/sun3/sun3/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.8 1999/01/10 13:34:19 niklas Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.9 1999/08/17 10:32:18 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.35 1996/04/26 18:38:06 gwr Exp $ */ /* @@ -73,8 +73,10 @@ * than the parent. Returns 1 in the child process, 0 in the parent. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct pcb *p1pcb = &p1->p_addr->u_pcb; register struct pcb *p2pcb = &p2->p_addr->u_pcb; @@ -116,6 +118,12 @@ cpu_fork(p1, p2) bcopy(p1->p_md.md_regs, p2tf, sizeof(*p2tf)); /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + p2tf->tf_regs[15] = (u_int)stack + stacksize; + + /* * Create a "switch frame" such that when cpu_switch returns, * this process will be in proc_do_uret() going to user mode. */ diff --git a/sys/arch/vax/vax/vm_machdep.c b/sys/arch/vax/vax/vm_machdep.c index f6351660939..1e25254e5a9 100644 --- a/sys/arch/vax/vax/vm_machdep.c +++ b/sys/arch/vax/vax/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.14 1999/01/10 13:34:19 niklas Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.15 1999/08/17 10:32:18 niklas Exp $ */ /* $NetBSD: vm_machdep.c,v 1.33 1997/07/06 22:38:22 ragge Exp $ */ /* @@ -98,8 +98,10 @@ pagemove(from, to, size) * forking. */ void -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) struct proc *p1, *p2; + void *stack; + size_t stacksize; { struct pcb *nyproc; struct trapframe *tf; @@ -137,6 +139,13 @@ cpu_fork(p1, p2) /* General registers as taken from userspace */ /* trapframe should be synced with pcb */ bcopy(&tf->r2,&nyproc->R[2],10*sizeof(int)); + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->sp = (u_long)stack + stacksize; + nyproc->AP = tf->ap; nyproc->FP = tf->fp; nyproc->USP = tf->sp; diff --git a/sys/arch/wgrisc/wgrisc/vm_machdep.c b/sys/arch/wgrisc/wgrisc/vm_machdep.c index 769db366156..b94a9c556a2 100644 --- a/sys/arch/wgrisc/wgrisc/vm_machdep.c +++ b/sys/arch/wgrisc/wgrisc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.2 1998/07/28 00:13:58 millert Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.3 1999/08/17 10:32:18 niklas Exp $ */ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 @@ -39,7 +39,7 @@ * from: Utah Hdr: vm_machdep.c 1.21 91/04/06 * * from: @(#)vm_machdep.c 8.3 (Berkeley) 1/4/94 - * $Id: vm_machdep.c,v 1.2 1998/07/28 00:13:58 millert Exp $ + * $Id: vm_machdep.c,v 1.3 1999/08/17 10:32:18 niklas Exp $ */ @@ -73,13 +73,16 @@ vm_offset_t kmem_alloc_wait_align(); * address in each process; in the future we will probably relocate * the frame pointers on the stack after copying. */ -cpu_fork(p1, p2) +cpu_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct user *up = p2->p_addr; register pt_entry_t *pte; register int i; extern struct proc *cpuFPCurProcPtr; + struct frame *f; p2->p_md.md_regs = up->u_pcb.pcb_regs; p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED; @@ -112,6 +115,14 @@ cpu_fork(p1, p2) /* cache segtab for ULTBMiss() */ p2->p_addr->u_pcb.pcb_segtab = (void *)p2->p_vmspace->vm_pmap.pm_segtab; +#ifdef notyet + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + /* XXX How??? */; +#endif + /* * Arrange for a non-local goto when the new process * is started, to resume here, returning nonzero from setjmp. diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index d56ed9a12bf..b27d668fc31 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.39 1999/07/15 14:07:41 art Exp $ */ +/* $OpenBSD: init_main.c,v 1.40 1999/08/17 10:32:18 niklas Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -405,7 +405,7 @@ main(framep) siginit(p); /* Create process 1 (init(8)). */ - if (fork1(p, ISFORK, 0, rval)) + if (fork1(p, ISFORK, 0, NULL, 0, rval)) panic("fork init"); #ifdef cpu_set_init_frame /* XXX should go away */ if (rval[1]) { diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index ef16a476ee7..364e767b3f6 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.23 1999/08/15 00:07:43 pjanzen Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.24 1999/08/17 10:32:18 niklas Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -78,7 +78,7 @@ sys_fork(p, v, retval) void *v; register_t *retval; { - return (fork1(p, ISFORK, 0, retval)); + return (fork1(p, ISFORK, 0, NULL, 0, retval)); } /*ARGSUSED*/ @@ -88,7 +88,7 @@ sys_vfork(p, v, retval) void *v; register_t *retval; { - return (fork1(p, ISVFORK, 0, retval)); + return (fork1(p, ISVFORK, 0, NULL, 0, retval)); } int @@ -101,14 +101,16 @@ sys_rfork(p, v, retval) syscallarg(int) flags; } */ *uap = v; - return (fork1(p, ISRFORK, SCARG(uap, flags), retval)); + return (fork1(p, ISRFORK, SCARG(uap, flags), NULL, 0, retval)); } int -fork1(p1, forktype, rforkflags, retval) +fork1(p1, forktype, rforkflags, stack, stacksize, retval) register struct proc *p1; int forktype; int rforkflags; + void *stack; + size_t stacksize; register_t *retval; { register struct proc *p2; @@ -334,7 +336,7 @@ again: */ retval[0] = 0; retval[1] = 1; - if (vm_fork(p1, p2)) + if (vm_fork(p1, p2, stack, stacksize)) return (0); #else /* @@ -342,9 +344,11 @@ again: * different path later. */ #if defined(UVM) - uvm_fork(p1, p2, (forktype == ISRFORK && (rforkflags & RFMEM)) ? TRUE : FALSE); + uvm_fork(p1, p2, + (forktype == ISRFORK && (rforkflags & RFMEM)) ? TRUE : FALSE, + stack, stacksize); #else /* UVM */ - vm_fork(p1, p2); + vm_fork(p1, p2, stack, stacksize); #endif /* UVM */ #endif vm = p2->p_vmspace; diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 21e11e5cf04..37b488c65be 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_kthread.c,v 1.3 1999/01/26 23:07:26 niklas Exp $ */ +/* $OpenBSD: kern_kthread.c,v 1.4 1999/08/17 10:32:18 niklas Exp $ */ /* $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $ */ /*- @@ -83,7 +83,8 @@ kthread_create(func, arg, newpp, fmt, va_alist) * descriptors and don't leave the exit status around for the * parent to wait for. */ - error = fork1(&proc0, ISRFORK, RFPROC | RFMEM | RFFDG | RFNOWAIT, rv); + error = fork1(&proc0, ISRFORK, RFPROC | RFMEM | RFFDG | RFNOWAIT, NULL, + 0, rv); if (error) return (error); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 57666567e22..19268fcb57f 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.24 1999/02/26 02:30:33 art Exp $ */ +/* $OpenBSD: proc.h,v 1.25 1999/08/17 10:32:18 niklas Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -333,7 +333,7 @@ int tsleep __P((void *chan, int pri, char *wmesg, int timo)); void unsleep __P((struct proc *)); void wakeup __P((void *chan)); void exit1 __P((struct proc *, int)); -int fork1 __P((struct proc *, int, int, register_t *)); +int fork1 __P((struct proc *, int, int, void *, size_t, register_t *)); #define ISFORK 0 #define ISVFORK 1 #define ISRFORK 2 diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h index 1389cb1e221..a18c0ae1ec8 100644 --- a/sys/uvm/uvm_extern.h +++ b/sys/uvm/uvm_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_extern.h,v 1.3 1999/07/23 14:47:06 ho Exp $ */ +/* $OpenBSD: uvm_extern.h,v 1.4 1999/08/17 10:32:19 niklas Exp $ */ /* $NetBSD: uvm_extern.h,v 1.21 1998/09/08 23:44:21 thorpej Exp $ */ /* @@ -274,7 +274,8 @@ int uvm_fault __P((vm_map_t, vaddr_t, #if defined(KGDB) void uvm_chgkprot __P((caddr_t, size_t, int)); #endif -void uvm_fork __P((struct proc *, struct proc *, boolean_t)); +void uvm_fork __P((struct proc *, struct proc *, boolean_t, + void *, size_t)); void uvm_exit __P((struct proc *)); void uvm_init_limits __P((struct proc *)); boolean_t uvm_kernacc __P((caddr_t, size_t, int)); diff --git a/sys/uvm/uvm_glue.c b/sys/uvm/uvm_glue.c index dd27027eb32..dfbf67de7f6 100644 --- a/sys/uvm/uvm_glue.c +++ b/sys/uvm/uvm_glue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_glue.c,v 1.2 1999/02/26 05:32:06 art Exp $ */ +/* $OpenBSD: uvm_glue.c,v 1.3 1999/08/17 10:32:19 niklas Exp $ */ /* $NetBSD: uvm_glue.c,v 1.15 1998/10/19 22:21:19 tron Exp $ */ /* @@ -266,9 +266,11 @@ uvm_vsunlock(p, addr, len) * than just hang */ void -uvm_fork(p1, p2, shared) +uvm_fork(p1, p2, shared, stack, stacksize) struct proc *p1, *p2; boolean_t shared; + void *stack; + size_t stacksize; { struct user *up = p2->p_addr; int rv; @@ -304,12 +306,12 @@ uvm_fork(p1, p2, shared) ((caddr_t)&up->u_stats.pstat_endcopy - (caddr_t)&up->u_stats.pstat_startcopy)); -/* + /* * cpu_fork will copy and update the kernel stack and pcb, and make * the child ready to run. The child will exit directly to user * mode on its first time slice, and will not return here. */ - cpu_fork(p1, p2); + cpu_fork(p1, p2, stack, stacksize); } /* diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index d6265da7915..01b754c0f92 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_extern.h,v 1.15 1998/03/01 00:38:02 niklas Exp $ */ +/* $OpenBSD: vm_extern.h,v 1.16 1999/08/17 10:32:19 niklas Exp $ */ /* $NetBSD: vm_extern.h,v 1.20 1996/04/23 12:25:23 christos Exp $ */ /*- @@ -138,9 +138,9 @@ void vm_fault_unwire __P((vm_map_t, vm_offset_t, vm_offset_t)); int vm_fault_wire __P((vm_map_t, vm_offset_t, vm_offset_t)); #if !defined(UVM) #ifdef __FORK_BRAINDAMAGE -int vm_fork __P((struct proc *, struct proc *)); +int vm_fork __P((struct proc *, struct proc *, void *, size_t)); #else -void vm_fork __P((struct proc *, struct proc *)); +void vm_fork __P((struct proc *, struct proc *, void *, size_t)); #endif #endif int vm_inherit __P((vm_map_t, @@ -176,9 +176,9 @@ void vmapbuf __P((struct buf *, vm_size_t)); void vunmapbuf __P((struct buf *, vm_size_t)); void pagemove __P((caddr_t, caddr_t, size_t)); #ifdef __FORK_BRAINDAMAGE -int cpu_fork __P((struct proc *, struct proc *)); +int cpu_fork __P((struct proc *, struct proc *, void *, size_t)); #else -void cpu_fork __P((struct proc *, struct proc *)); +void cpu_fork __P((struct proc *, struct proc *, void *, size_t)); #endif #ifndef cpu_swapin void cpu_swapin __P((struct proc *)); diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index 2706d3fe359..435c286b0aa 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_glue.c,v 1.32 1999/06/23 09:44:29 art Exp $ */ +/* $OpenBSD: vm_glue.c,v 1.33 1999/08/17 10:32:19 niklas Exp $ */ /* $NetBSD: vm_glue.c,v 1.55.4.1 1996/06/13 17:25:45 cgd Exp $ */ /* @@ -211,8 +211,10 @@ int #else void #endif -vm_fork(p1, p2) +vm_fork(p1, p2, stack, stacksize) register struct proc *p1, *p2; + void *stack; + size_t stacksize; { register struct user *up = p2->p_addr; @@ -271,7 +273,7 @@ vm_fork(p1, p2) * It returns twice, once in the parent process and * once in the child. */ - return (cpu_fork(p1, p2)); + return (cpu_fork(p1, p2, stack, stacksize)); #else /* * cpu_fork will copy and update the kernel stack and pcb, @@ -279,7 +281,7 @@ vm_fork(p1, p2) * directly to user mode on its first time slice, and will * not return here. */ - cpu_fork(p1, p2); + cpu_fork(p1, p2, stack, stack_size); #endif } |