summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2012-11-01 21:01:44 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2012-11-01 21:01:44 +0000
commit5fb77fc211900ec373a25d705a8901cab6582053 (patch)
treef55c209987b969b2fbb4b12ce853e81c1b15a7fa
parent8751271cec15cc354a93a906e89ac2aab63f37f7 (diff)
In cpu_fork(), correctly set up the stack of the new process if required. This
repairs tfork_thread() operation.
-rw-r--r--sys/arch/alpha/alpha/vm_machdep.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/sys/arch/alpha/alpha/vm_machdep.c b/sys/arch/alpha/alpha/vm_machdep.c
index 935965bcb35..9508776e257 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.37 2009/01/28 08:02:02 grange Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.38 2012/11/01 21:01:43 miod Exp $ */
/* $NetBSD: vm_machdep.c,v 1.55 2000/03/29 03:49:48 simonb Exp $ */
/*
@@ -164,11 +164,15 @@ 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.
* We do this as cheaply as possible, copying only the active
* part of the stack. The stack and pcb need to agree;
*/
- p2->p_addr->u_pcb = p1->p_addr->u_pcb;
- p2->p_addr->u_pcb.pcb_hw.apcb_usp = alpha_pal_rdusp();
+ up->u_pcb = p1->p_addr->u_pcb;
+ if (stack != NULL)
+ up->u_pcb.pcb_hw.apcb_usp = (u_long)stack + stacksize;
+ else
+ up->u_pcb.pcb_hw.apcb_usp = alpha_pal_rdusp();
/*
* Arrange for a non-local goto when the new process
@@ -209,12 +213,6 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
p2tf->tf_regs[FRAME_A4] = 1; /* is child */
/*
- * If specified, 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!