diff options
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 } |