summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/alpha/alpha/vm_machdep.c12
-rw-r--r--sys/arch/amiga/amiga/vm_machdep.c13
-rw-r--r--sys/arch/arm32/arm32/vm_machdep.c11
-rw-r--r--sys/arch/atari/atari/vm_machdep.c11
-rw-r--r--sys/arch/hp300/hp300/vm_machdep.c13
-rw-r--r--sys/arch/hppa/hppa/vm_machdep.c13
-rw-r--r--sys/arch/i386/i386/vm_machdep.c13
-rw-r--r--sys/arch/kbus/kbus/vm_machdep.c14
-rw-r--r--sys/arch/mac68k/mac68k/vm_machdep.c14
-rw-r--r--sys/arch/mips/mips/vm_machdep.c14
-rw-r--r--sys/arch/mvme68k/mvme68k/vm_machdep.c13
-rw-r--r--sys/arch/mvme88k/mvme88k/vm_machdep.c12
-rw-r--r--sys/arch/pc532/pc532/vm_machdep.c6
-rw-r--r--sys/arch/pmax/pmax/vm_machdep.c12
-rw-r--r--sys/arch/powerpc/powerpc/vm_machdep.c13
-rw-r--r--sys/arch/sparc/sparc/vm_machdep.c12
-rw-r--r--sys/arch/sun3/sun3/vm_machdep.c12
-rw-r--r--sys/arch/vax/vax/vm_machdep.c13
-rw-r--r--sys/arch/wgrisc/wgrisc/vm_machdep.c17
-rw-r--r--sys/kern/init_main.c4
-rw-r--r--sys/kern/kern_fork.c20
-rw-r--r--sys/kern/kern_kthread.c5
-rw-r--r--sys/sys/proc.h4
-rw-r--r--sys/uvm/uvm_extern.h5
-rw-r--r--sys/uvm/uvm_glue.c10
-rw-r--r--sys/vm/vm_extern.h10
-rw-r--r--sys/vm/vm_glue.c10
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
}