diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2001-11-06 18:41:11 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2001-11-06 18:41:11 +0000 |
commit | 89ae7820c1a454d61cd281925d300bf324cfb4a3 (patch) | |
tree | 322119c116dc2ae1a396e832aac803b47d2df136 /sys/arch/sun3 | |
parent | 1c0a1a534d87ced0c6089cb972b59491152bbdfa (diff) |
Let fork1, uvm_fork, and cpu_fork take a function/argument pair as argument,
instead of doing fork1, cpu_set_kpc. This lets us retire cpu_set_kpc and
avoid a multiprocessor race.
This commit breaks vax because it doesn't look like any other arch, someone
working on vax might want to look at this and try to adapt the code to be
more like the rest of the world.
Idea and uvm parts from NetBSD.
Diffstat (limited to 'sys/arch/sun3')
-rw-r--r-- | sys/arch/sun3/include/cpu.h | 5 | ||||
-rw-r--r-- | sys/arch/sun3/include/machdep.h | 4 | ||||
-rw-r--r-- | sys/arch/sun3/sun3/trap.c | 32 | ||||
-rw-r--r-- | sys/arch/sun3/sun3/vm_machdep.c | 69 |
4 files changed, 21 insertions, 89 deletions
diff --git a/sys/arch/sun3/include/cpu.h b/sys/arch/sun3/include/cpu.h index a9093530e2a..0c7d910b1e4 100644 --- a/sys/arch/sun3/include/cpu.h +++ b/sys/arch/sun3/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.13 2001/09/28 20:40:20 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.14 2001/11/06 18:41:10 art Exp $ */ /* $NetBSD: cpu.h,v 1.20 1995/12/21 05:02:10 mycroft Exp $ */ /* @@ -157,9 +157,6 @@ void savectx __P((struct pcb *)); void switch_exit __P((struct proc *)); void proc_trampoline __P((void)); -/* trap.c */ -void child_return __P((void *)); - #endif /* _KERNEL */ /* diff --git a/sys/arch/sun3/include/machdep.h b/sys/arch/sun3/include/machdep.h index ac195f63f87..51f20b4e3c4 100644 --- a/sys/arch/sun3/include/machdep.h +++ b/sys/arch/sun3/include/machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.h,v 1.15 2001/08/25 11:37:26 espie Exp $ */ +/* $OpenBSD: machdep.h,v 1.16 2001/11/06 18:41:10 art Exp $ */ /* * Copyright (c) 1994 Gordon W. Ross @@ -84,8 +84,6 @@ void cache_flush_context(void); int cachectl __P((int req, caddr_t addr, int len)); -void child_return __P((void *)); - void cninit __P((void)); void dumpconf __P((void)); diff --git a/sys/arch/sun3/sun3/trap.c b/sys/arch/sun3/sun3/trap.c index f5f3c079285..f7242c0c6a5 100644 --- a/sys/arch/sun3/sun3/trap.c +++ b/sys/arch/sun3/sun3/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.26 2001/09/14 09:12:21 art Exp $ */ +/* $OpenBSD: trap.c,v 1.27 2001/11/06 18:41:10 art Exp $ */ /* $NetBSD: trap.c,v 1.63-1.65ish 1997/01/16 15:41:40 gwr Exp $ */ /* @@ -86,7 +86,7 @@ int nodb_trap __P((int type, struct frame *)); int astpending; int want_resched; -static void userret __P((struct proc *, struct frame *, u_quad_t)); +void userret __P((struct proc *, struct frame *, u_quad_t)); char *trap_type[] = { "Bus error", @@ -147,7 +147,7 @@ int mmupid = -1; * trap and syscall both need the following work done before * returning to user mode. */ -static void +void userret(p, fp, oticks) register struct proc *p; register struct frame *fp; @@ -748,32 +748,6 @@ syscall(code, frame) } /* - * Set up return-value registers as fork() libc stub expects, - * and do normal return-to-user-mode stuff. - */ -void -child_return(p) - void *p; -{ - struct frame *f; - - f = (struct frame *)((struct proc *)p)->p_md.md_regs; - f->f_regs[D0] = 0; - f->f_sr &= ~PSL_C; - f->f_format = FMT0; - - /* - * Old ticks (3rd arg) is zero so we will charge the child - * for any clock ticks that might happen before this point. - */ - userret((struct proc *)p, f, 0); -#ifdef KTRACE - if (KTRPOINT((struct proc *)p, KTR_SYSRET)) - ktrsysret(((struct proc *)p), SYS_fork, 0, 0); -#endif -} - -/* * This is used if we hit a kernel breakpoint or trace trap * when there is no debugger installed (or not attached). * Drop into the PROM temporarily... diff --git a/sys/arch/sun3/sun3/vm_machdep.c b/sys/arch/sun3/sun3/vm_machdep.c index bf7f4f59b99..9b6daee2307 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.20 2001/09/19 20:50:57 mickey Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.21 2001/11/06 18:41:10 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.35 1996/04/26 18:38:06 gwr Exp $ */ /* @@ -72,15 +72,22 @@ * than the parent. Returns 1 in the child process, 0 in the parent. */ void -cpu_fork(p1, p2, stack, stacksize) - register struct proc *p1, *p2; +cpu_fork(p1, p2, stack, stacksize, func, arg) + struct proc *p1, *p2; void *stack; size_t stacksize; + void (*func)(void *); + void *arg; { - register struct pcb *p1pcb = &p1->p_addr->u_pcb; - register struct pcb *p2pcb = &p2->p_addr->u_pcb; - register struct trapframe *p2tf; - register struct switchframe *p2sf; + struct pcb *p1pcb = &p1->p_addr->u_pcb; + struct pcb *p2pcb = &p2->p_addr->u_pcb; + struct trapframe *p2tf; + struct switchframe *p2sf; + struct ksigframe { + struct switchframe sf; + void (*func) (void *); + void *arg; + } *ksfp; /* * Before copying the PCB from the current process, @@ -130,53 +137,9 @@ cpu_fork(p1, p2, stack, stacksize) p2sf->sf_pc = (u_int)proc_do_uret; p2pcb->pcb_regs[11] = (int)p2sf; /* SSP */ - /* - * This will "push a call" to an arbitrary kernel function - * onto the stack of p2, very much like signal delivery. - * When p2 runs, it will find itself in child_return(). - */ - cpu_set_kpc(p2, child_return, p2); -} - -/* - * cpu_set_kpc: - * - * Arrange for in-kernel execution of a process to continue in the - * named function, as if that function were called with one argument, - * the current process's process pointer. - * - * Note that it's assumed that when the named process returns, - * rei() should be invoked, to return to user mode. That is - * accomplished by having cpu_fork set the initial frame with a - * return address pointing to proc_do_uret() which does the rte. - * - * The design allows this function to be implemented as a general - * "kernel sendsig" utility, that can "push" a call to a kernel - * function onto any other process kernel stack, in a way very - * similar to how signal delivery works on a user stack. When - * the named process is switched to, it will call the function - * we "pushed" and then proc_trampoline will pop the args that - * were pushed here and return to where it would have returned - * before we "pushed" this call. - */ -void -cpu_set_kpc(prc, func, arg) - struct proc *prc; - void (*func) (void *); - void *arg; -{ - struct pcb *pcbp; - struct ksigframe { - struct switchframe sf; - void (*func) (void *); - void *arg; - } *ksfp; - - pcbp = &prc->p_addr->u_pcb; - /* Push a ksig frame onto the kernel stack. */ - ksfp = (struct ksigframe *)pcbp->pcb_regs[11] - 1; - pcbp->pcb_regs[11] = (int)ksfp; + ksfp = (struct ksigframe *)p2pcb->pcb_regs[11] - 1; + p2pcb->pcb_regs[11] = (int)ksfp; /* Now fill it in for proc_trampoline. */ ksfp->sf.sf_pc = (u_int)proc_trampoline; |