diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2017-02-12 04:55:09 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2017-02-12 04:55:09 +0000 |
commit | 89043ff36c6d6b7d281d035919b813f9866d1e68 (patch) | |
tree | 876e1797e6617d45dc347d704757015e0635dd5b /sys/arch | |
parent | 68a5515f6186c6c1d00d6abe9453463fbdc66c99 (diff) |
Split up fork1():
- FORK_THREAD handling is a totally separate function, thread_fork(),
that is only used by sys___tfork() and which loses the flags, func,
arg, and newprocp parameters and gains tcb parameter to guarantee
the new thread's TCB is set before the creating thread returns
- fork1() loses its stack and tidptr parameters
Common bits factor out:
- struct proc allocation and initialization moves to thread_new()
- maxthread handling moves to fork_check_maxthread()
- setting the new thread running moves to fork_thread_start()
The MD cpu_fork() function swaps its unused stacksize parameter for
a tcb parameter.
luna88k testing by aoyama@, alpha testing by dlg@
ok mpi@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/alpha/alpha/vm_machdep.c | 33 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/vm_machdep.c | 12 | ||||
-rw-r--r-- | sys/arch/arm/arm/vm_machdep.c | 38 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/vm_machdep.c | 10 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/vm_machdep.c | 8 | ||||
-rw-r--r-- | sys/arch/i386/i386/vm_machdep.c | 13 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/vm_machdep.c | 19 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/vm_machdep.c | 16 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/vm_machdep.c | 10 | ||||
-rw-r--r-- | sys/arch/sh/sh/vm_machdep.c | 29 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/vm_machdep.c | 34 |
11 files changed, 106 insertions, 116 deletions
diff --git a/sys/arch/alpha/alpha/vm_machdep.c b/sys/arch/alpha/alpha/vm_machdep.c index 7ff834b9ec4..48f6ec11f2a 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.45 2016/10/04 05:55:09 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.46 2017/02/12 04:55:08 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.55 2000/03/29 03:49:48 simonb Exp $ */ /* @@ -71,24 +71,19 @@ cpu_exit(p) * Copy and update the pcb and trap frame, making the child ready to run. * * Rig the child's kernel stack so that it will start out in - * switch_trampoline() and call child_return() with p2 as an - * argument. This causes the newly-created child process to go - * directly to user level with an apparent return value of 0 from - * fork(), while the parent process returns normally. + * proc_trampoline() and call 'func' with 'arg' as an argument. + * For normal processes this is child_return(), which causes the + * child to go directly to user level with an apparent return value + * of 0 from fork(), while the parent process returns normally. + * For kernel threads this will be a function that never return. * - * p1 is the process being forked; - * - * If an alternate user-level stack is requested (with non-NULL stack arg), - * set up the user stack pointer - * accordingly. + * An alternate user-level stack or TCB can be requested by passing + * a non-NULL value; these are poked into the PCB so they're in + * effect at the initial return to userspace. */ void -cpu_fork(p1, p2, stack, stacksize, func, arg) - struct proc *p1, *p2; - void *stack; - size_t stacksize; - void (*func)(void *); - void *arg; +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, + void (*func)(void *), void *arg) { struct user *up = p2->p_addr; @@ -115,15 +110,17 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) /* * Copy pcb and stack from proc p1 to p2. - * If specified, give the child a different stack. + * If specified, give the child a different stack and/or TCB. * We do this as cheaply as possible, copying only the active * part of the stack. The stack and pcb need to agree; */ up->u_pcb = p1->p_addr->u_pcb; if (stack != NULL) - up->u_pcb.pcb_hw.apcb_usp = (u_long)stack + stacksize; + up->u_pcb.pcb_hw.apcb_usp = (u_long)stack; else up->u_pcb.pcb_hw.apcb_usp = alpha_pal_rdusp(); + if (tcb != NULL) + up->u_pcb.pcb_hw.apcb_unique = (unsigned long)tcb; /* * Arrange for a non-local goto when the new process diff --git a/sys/arch/amd64/amd64/vm_machdep.c b/sys/arch/amd64/amd64/vm_machdep.c index 2b402e5ec74..42dc47f92ea 100644 --- a/sys/arch/amd64/amd64/vm_machdep.c +++ b/sys/arch/amd64/amd64/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.35 2016/04/03 19:49:35 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.36 2017/02/12 04:55:08 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.1 2003/04/26 18:39:33 fvdl Exp $ */ /*- @@ -66,10 +66,10 @@ void setredzone(struct proc *); * Finish a fork operation, with process p2 nearly set up. * Copy and update the kernel stack and pcb, making the child * ready to run, and marking it so that it can return differently - * than the parent. Returns 1 in the child process, 0 in the parent. + * than the parent. */ void -cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, void (*func)(void *), void *arg) { struct pcb *pcb = &p2->p_addr->u_pcb; @@ -112,10 +112,12 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, setredzone(p2); /* - * If specified, give the child a different stack. + * If specified, give the child a different stack and/or TCB */ if (stack != NULL) - tf->tf_rsp = (u_int64_t)stack + stacksize; + tf->tf_rsp = (u_int64_t)stack; + if (tcb != NULL) + pcb->pcb_fsbase = (u_int64_t)tcb; sf = (struct switchframe *)tf - 1; sf->sf_r12 = (u_int64_t)func; diff --git a/sys/arch/arm/arm/vm_machdep.c b/sys/arch/arm/arm/vm_machdep.c index 38dba6d7d77..9b2a00a92f5 100644 --- a/sys/arch/arm/arm/vm_machdep.c +++ b/sys/arch/arm/arm/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.18 2016/07/31 09:18:01 jsg Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.19 2017/02/12 04:55:08 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.31 2004/01/04 11:33:29 jdolecek Exp $ */ /* @@ -80,24 +80,21 @@ extern void proc_trampoline (void); /* * Finish a fork operation, with process p2 nearly set up. * Copy and update the pcb and trap frame, making the child ready to run. - * - * Rig the child's kernel stack so that it will start out in - * proc_trampoline() and call child_return() with p2 as an - * argument. This causes the newly-created child process to go - * directly to user level with an apparent return value of 0 from - * fork(), while the parent process returns normally. * - * p1 is the process being forked; if p1 == &proc0, we are creating - * a kernel thread, and the return path and argument are specified with - * `func' and `arg'. + * Rig the child's kernel stack so that it will start out in + * proc_trampoline() and call 'func' with 'arg' as an argument. + * For normal processes this is child_return(), which causes the + * child to go directly to user level with an apparent return value + * of 0 from fork(), while the parent process returns normally. + * For kernel threads this will be a function that never return. * - * If an alternate user-level stack is requested (with non-zero values - * in both the stack and stacksize args), set up the user stack pointer - * accordingly. + * An alternate user-level stack or TCB can be requested by passing + * a non-NULL value; these are poked into the PCB so they're in + * effect at the initial return to userspace. */ void -cpu_fork(struct proc *p1, struct proc *p2, void *stack, - size_t stacksize, void (*func) (void *), void *arg) +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, + void (*func)(void *), void *arg) { struct pcb *pcb = (struct pcb *)&p2->p_addr->u_pcb; struct trapframe *tf; @@ -130,16 +127,17 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, pmap_activate(p2); - p2->p_addr->u_pcb.pcb_tf = tf = - (struct trapframe *)pcb->pcb_un.un_32.pcb32_sp - 1; + pcb->pcb_tf = tf = (struct trapframe *)pcb->pcb_un.un_32.pcb32_sp - 1; *tf = *p1->p_addr->u_pcb.pcb_tf; /* - * If specified, give the child a different stack (make sure - * it's 8-byte aligned). + * If specified, give the child a different stack and/or TCB. + * Enforce 8-byte alignment on the stack. */ if (stack != NULL) - tf->tf_usr_sp = ((vaddr_t)(stack) + stacksize) & -8; + tf->tf_usr_sp = (vaddr_t)stack & -8; + if (tcb != NULL) + p2->p_addr->u_pcb.pcb_tcb = tcb; sf = (struct switchframe *)tf - 1; sf->sf_r4 = (u_int)func; diff --git a/sys/arch/arm64/arm64/vm_machdep.c b/sys/arch/arm64/arm64/vm_machdep.c index c2e42e53234..3a879b9dc26 100644 --- a/sys/arch/arm64/arm64/vm_machdep.c +++ b/sys/arch/arm64/arm64/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.1 2016/12/17 23:38:33 patrick Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.2 2017/02/12 04:55:08 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.1 2003/04/26 18:39:33 fvdl Exp $ */ /*- @@ -66,7 +66,7 @@ * than the parent. Returns 1 in the child process, 0 in the parent. */ void -cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, void (*func)(void *), void *arg) { struct pcb *pcb = (struct pcb *)&p2->p_addr->u_pcb; @@ -86,11 +86,13 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, - 0x10); tf = (struct trapframe *)STACKALIGN(tf); - p2->p_addr->u_pcb.pcb_tf = tf; + pcb->pcb_tf = tf; *tf = *p1->p_addr->u_pcb.pcb_tf; if (stack != NULL) - tf->tf_sp = STACKALIGN((u_int)(stack) + stacksize); + tf->tf_sp = STACKALIGN((u_int)(stack)); + if (tcb != NULL) + pcb->pcb_tcb = tcb; sf = (struct switchframe *)tf - 1; sf->sf_x19 = (uint64_t)func; diff --git a/sys/arch/hppa/hppa/vm_machdep.c b/sys/arch/hppa/hppa/vm_machdep.c index 11bceafc94c..eb517d2def7 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.81 2015/05/05 02:13:46 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.82 2017/02/12 04:55:08 guenther Exp $ */ /* * Copyright (c) 1999-2004 Michael Shalayeff @@ -49,7 +49,7 @@ extern struct pool hppa_fppl; void -cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, void (*func)(void *), void *arg) { struct pcb *pcbp; @@ -102,10 +102,12 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, (curcpu()->ci_psw & PSL_O); /* - * If specified, give the child a different stack. + * If specified, give the child a different stack and/or TCB */ if (stack != NULL) setstack(tf, (u_long)stack, 0); /* XXX ignore error? */ + if (tcb != NULL) + tf->tf_cr27 = (u_long)tcb; /* * Build stack frames for the cpu_switchto & co. diff --git a/sys/arch/i386/i386/vm_machdep.c b/sys/arch/i386/i386/vm_machdep.c index 49901d20f3e..182795c274f 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.64 2016/04/03 17:45:30 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.65 2017/02/12 04:55:08 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.61 1996/05/03 19:42:35 christos Exp $ */ /*- @@ -67,12 +67,9 @@ * Copy and update the kernel stack and pcb, making the child * ready to run, and marking it so that it can return differently * than the parent. Returns 1 in the child process, 0 in the parent. - * We currently double-map the user area so that the stack is at the same - * address in each process; in the future we will probably relocate - * the frame pointers on the stack after copying. */ void -cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, void (*func)(void *), void *arg) { struct pcb *pcb = &p2->p_addr->u_pcb; @@ -104,10 +101,12 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, *tf = *p1->p_md.md_regs; /* - * If specified, give the child a different stack. + * If specified, give the child a different stack and/or TCB */ if (stack != NULL) - tf->tf_esp = (u_int)stack + stacksize; + tf->tf_esp = (u_int)stack; + if (tcb != NULL) + i386_set_threadbase(p2, (uint32_t)tcb, TSEG_GS); sf = (struct switchframe *)tf - 1; sf->sf_esi = (int)func; diff --git a/sys/arch/m88k/m88k/vm_machdep.c b/sys/arch/m88k/m88k/vm_machdep.c index d4cb331f49b..c247482c54f 100644 --- a/sys/arch/m88k/m88k/vm_machdep.c +++ b/sys/arch/m88k/m88k/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.24 2015/05/05 02:13:47 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.25 2017/02/12 04:55:08 guenther Exp $ */ /* * Copyright (c) 1998 Steve Murphree, Jr. @@ -67,18 +67,11 @@ extern void switch_exit(struct proc *); * Copy and update the kernel stack and pcb, making the child * ready to run, and marking it so that it can return differently * than the parent. Returns 1 in the child process, 0 in the parent. - * We currently double-map the user area so that the stack is at the same - * address in each process; in the future we will probably relocate - * the frame pointers on the stack after copying. */ void -cpu_fork(p1, p2, stack, stacksize, func, arg) - struct proc *p1, *p2; - void *stack; - size_t stacksize; - void (*func)(void *); - void *arg; +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, + void (*func)(void *), void *arg) { struct ksigframe { void (*func)(void *); @@ -100,10 +93,12 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) p2->p_md.md_tf = (struct trapframe *)USER_REGS(p2); /* - * If specified, give the child a different stack. + * If specified, give the child a different stack and/or TCB. */ if (stack != NULL) - USER_REGS(p2)->r[31] = (u_int)stack + stacksize; + USER_REGS(p2)->r[31] = (u_int)stack; + if (tcb != NULL) + USER_REGS(p2)->r[27] = (u_int)tcb; ksfp = (struct ksigframe *)((char *)p2->p_addr + USPACE) - 1; ksfp->func = func; diff --git a/sys/arch/mips64/mips64/vm_machdep.c b/sys/arch/mips64/mips64/vm_machdep.c index f49bed30773..366d7c6969a 100644 --- a/sys/arch/mips64/mips64/vm_machdep.c +++ b/sys/arch/mips64/mips64/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.33 2016/03/06 19:42:27 mpi Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.34 2017/02/12 04:55:08 guenther Exp $ */ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 @@ -61,12 +61,8 @@ extern void proc_trampoline(void); * Finish a fork operation, with process p2 nearly set up. */ void -cpu_fork(p1, p2, stack, stacksize, func, arg) - struct proc *p1, *p2; - void *stack; - size_t stacksize; - void (*func)(void *); - void *arg; +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, + void (*func)(void *), void *arg) { struct cpu_info *ci = curcpu(); struct pcb *pcb; @@ -117,10 +113,12 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) p2->p_md.md_regs = &p2->p_addr->u_pcb.pcb_regs; /* - * If specified, give the child a different stack. + * If specified, give the child a different stack and/or TCB. */ if (stack != NULL) - p2->p_md.md_regs->sp = (u_int64_t)stack + stacksize; + p2->p_md.md_regs->sp = (u_int64_t)stack; + if (tcb != NULL) + TCB_SET(p2, tcb); /* * Copy the process control block to the new proc and diff --git a/sys/arch/powerpc/powerpc/vm_machdep.c b/sys/arch/powerpc/powerpc/vm_machdep.c index 43e18f7401e..fc64451a15c 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.48 2015/05/05 02:13:47 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.49 2017/02/12 04:55:08 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.1 1996/09/30 16:34:57 ws Exp $ */ /* @@ -49,7 +49,7 @@ * Finish a fork operation, with process p2 nearly set up. */ void -cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, void (*func)(void *), void *arg) { struct trapframe *tf; @@ -92,7 +92,11 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, */ if (stack != NULL) { tf = trapframe(p2); - tf->fixreg[1] = (register_t)stack + stacksize; + tf->fixreg[1] = (register_t)stack; + } + if (tcb != NULL) { + tf = trapframe(p2); + tf->fixreg[2] = (register_t)tcb; } stktop2 = (caddr_t)((u_long)stktop2 & ~15); /* Align stack pointer */ diff --git a/sys/arch/sh/sh/vm_machdep.c b/sys/arch/sh/sh/vm_machdep.c index 77b50487b5b..16645ebfd0d 100644 --- a/sys/arch/sh/sh/vm_machdep.c +++ b/sys/arch/sh/sh/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.13 2015/05/05 02:13:47 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.14 2017/02/12 04:55:08 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.53 2006/08/31 16:49:21 matt Exp $ */ /* @@ -120,23 +120,20 @@ extern void proc_trampoline(void); /* * Finish a fork operation, with process p2 nearly set up. * Copy and update the pcb and trap frame, making the child ready to run. - * + * * Rig the child's kernel stack so that it will start out in - * proc_trampoline() and call child_return() with p2 as an - * argument. This causes the newly-created child process to go - * directly to user level with an apparent return value of 0 from - * fork(), while the parent process returns normally. - * - * p1 is the process being forked; if p1 == &proc0, we are creating - * a kernel thread, and the return path and argument are specified with - * `func' and `arg'. + * proc_trampoline() and call 'func' with 'arg' as an argument. + * For normal processes this is child_return(), which causes the + * child to go directly to user level with an apparent return value + * of 0 from fork(), while the parent process returns normally. + * For kernel threads this will be a function that never return. * - * If an alternate user-level stack is requested (with non-zero values - * in both the stack and stacksize args), set up the user stack pointer - * accordingly. + * An alternate user-level stack or TCB can be requested by passing + * a non-NULL value; these are poked into the PCB so they're in + * effect at the initial return to userspace. */ void -cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, void (*func)(void *), void *arg) { struct pcb *pcb; @@ -213,7 +210,9 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, * If specified, give the child a different stack. */ if (stack != NULL) - tf->tf_r15 = (u_int)stack + stacksize; + tf->tf_r15 = (int)stack; + if (tcb != NULL) + tf->tf_gbr = (int)tcb; /* Setup switch frame */ sf = &pcb->pcb_sf; diff --git a/sys/arch/sparc64/sparc64/vm_machdep.c b/sys/arch/sparc64/sparc64/vm_machdep.c index c30e79a42a7..18e012ed879 100644 --- a/sys/arch/sparc64/sparc64/vm_machdep.c +++ b/sys/arch/sparc64/sparc64/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.35 2015/11/06 06:33:26 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.36 2017/02/12 04:55:08 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.38 2001/06/30 00:02:20 eeh Exp $ */ /* @@ -153,26 +153,19 @@ char cpu_forkname[] = "cpu_fork()"; * Copy and update the pcb and trap frame, making the child ready to run. * * Rig the child's kernel stack so that it will start out in - * proc_trampoline() and call child_return() with p2 as an - * argument. This causes the newly-created child process to go - * directly to user level with an apparent return value of 0 from - * fork(), while the parent process returns normally. + * proc_trampoline() and call 'func' with 'arg' as an argument. + * For normal processes this is child_return(), which causes the + * child to go directly to user level with an apparent return value + * of 0 from fork(), while the parent process returns normally. + * For kernel threads this will be a function that never return. * - * p1 is the process being forked; if p1 == &proc0, we are creating - * a kernel thread, and the return path and argument are specified with - * `func' and `arg'. - * - * If an alternate user-level stack is requested (with non-zero values - * in both the stack and stacksize args), set up the user stack pointer - * accordingly. + * An alternate user-level stack or TCB can be requested by passing + * a non-NULL value; these are poked into the PCB so they're in + * effect at the initial return to userspace. */ void -cpu_fork(p1, p2, stack, stacksize, func, arg) - struct proc *p1, *p2; - void *stack; - size_t stacksize; - void (*func)(void *); - void *arg; +cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, + void (*func)(void *), void *arg) { struct pcb *opcb = &p1->p_addr->u_pcb; struct pcb *npcb = &p2->p_addr->u_pcb; @@ -240,10 +233,11 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) * with space reserved for the frame, and zero the frame pointer. */ if (stack != NULL) { - tf2->tf_out[6] = (u_int64_t)(u_long)stack + stacksize - - (BIAS + CC64FSZ); + tf2->tf_out[6] = (u_int64_t)(u_long)stack - (BIAS + CC64FSZ); tf2->tf_in[6] = 0; } + if (tcb != NULL) + tf2->tf_global[7] = (u_int64_t)tcb; /* Construct kernel frame to return to in cpu_switch() */ rp = (struct rwindow *)((u_long)npcb + TOPFRAMEOFF); |