summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2017-02-12 04:55:09 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2017-02-12 04:55:09 +0000
commit89043ff36c6d6b7d281d035919b813f9866d1e68 (patch)
tree876e1797e6617d45dc347d704757015e0635dd5b /sys/arch/sparc64
parent68a5515f6186c6c1d00d6abe9453463fbdc66c99 (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/sparc64')
-rw-r--r--sys/arch/sparc64/sparc64/vm_machdep.c34
1 files changed, 14 insertions, 20 deletions
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);