diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2001-11-06 23:57:55 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2001-11-06 23:57:55 +0000 |
commit | 622b3c79012df892537a84831bb118f16af4400f (patch) | |
tree | 3484a56700f8b98c691e2b4cb1a186ff3dff6a87 /sys | |
parent | c35bb91d81e26f0219e95a6309ea71a1abd06556 (diff) |
Update and unbreak cpu_fork() - from NetBSD.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/vax/vax/trap.c | 95 | ||||
-rw-r--r-- | sys/arch/vax/vax/vm_machdep.c | 103 |
2 files changed, 100 insertions, 98 deletions
diff --git a/sys/arch/vax/vax/trap.c b/sys/arch/vax/vax/trap.c index 3d6760e13ba..6046656fdbb 100644 --- a/sys/arch/vax/vax/trap.c +++ b/sys/arch/vax/vax/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.17 2001/11/06 02:49:23 art Exp $ */ +/* $OpenBSD: trap.c,v 1.18 2001/11/06 23:57:54 miod Exp $ */ /* $NetBSD: trap.c,v 1.47 1999/08/21 19:26:20 matt Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. @@ -61,6 +61,8 @@ volatile int startsysc = 0, faultdebug = 0; #endif +static __inline void userret __P((struct proc *, struct trapframe *, u_quad_t)); + void arithflt __P((struct trapframe *)); void syscall __P((struct trapframe *)); @@ -96,6 +98,45 @@ int no_traps = 18; return; \ } +/* + * userret: + * + * Common code used by various exception handlers to + * return to usermode. + */ +static __inline void +userret(p, frame, oticks) + struct proc *p; + struct trapframe *frame; + u_quad_t oticks; +{ + int sig; + + /* Take pending signals. */ + while ((sig = CURSIG(p)) !=0) + postsig(sig); + p->p_priority = p->p_usrpri; + if (want_resched) { + /* + * We're being preempted. + */ + preempt(NULL); + while ((sig = CURSIG(p)) != 0) + postsig(sig); + } + + /* + * If profiling, charge system time to the trapped pc. + */ + if (p->p_flag & P_PROFIL) { + extern int psratio; + + addupc_task(p, frame->pc, + (int)(p->p_sticks - oticks) * psratio); + } + curpriority = p->p_priority; +} + void arithflt(frame) struct trapframe *frame; @@ -279,22 +320,7 @@ if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n", if (umode == 0) return; - while ((sig = CURSIG(p)) !=0) - postsig(sig); - p->p_priority = p->p_usrpri; - if (want_resched) { - /* - * We're being preempted. - */ - preempt(NULL); - while ((sig = CURSIG(p)) != 0) - postsig(sig); - } - if (p->p_flag & P_PROFIL) { - extern int psratio; - addupc_task(p, frame->pc, (int)(p->p_sticks-oticks) * psratio); - } - curpriority = p->p_priority; + userret(p, frame, oticks); } void @@ -323,7 +349,7 @@ syscall(frame) { struct sysent *callp; u_quad_t oticks; - int nsys, sig; + int nsys; int err, rval[2], args[8]; struct trapframe *exptr; struct proc *p = curproc; @@ -422,24 +448,25 @@ bad: exptr->psl |= PSL_C; break; } - p = curproc; - while ((sig = CURSIG(p)) !=0) - postsig(sig); - p->p_priority = p->p_usrpri; - if (want_resched) { - /* - * We're being preempted. - */ - preempt(NULL); - while ((sig = CURSIG(p)) != 0) - postsig(sig); - } - if (p->p_flag & P_PROFIL) { - extern int psratio; - addupc_task(p, frame->pc, (int)(p->p_sticks-oticks) * psratio); - } + + userret(p, frame, oticks); + #ifdef KTRACE if (KTRPOINT(p, KTR_SYSRET)) ktrsysret(p, frame->code, err, rval[0]); #endif } + +void +child_return(arg) + void *arg; +{ + struct proc *p = arg; + + userret(p, p->p_addr->u_pcb.framep, 0); + +#ifdef KTRACE + if (KTRPOINT(p, KTR_SYSRET)) + ktrsysret(p, SYS_fork, 0, 0); +#endif +} diff --git a/sys/arch/vax/vax/vm_machdep.c b/sys/arch/vax/vax/vm_machdep.c index 2c19e441160..a3ac5a22efb 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.26 2001/11/06 18:41:10 art Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.27 2001/11/06 23:57:54 miod Exp $ */ /* $NetBSD: vm_machdep.c,v 1.67 2000/06/29 07:14:34 mrg Exp $ */ /* @@ -113,10 +113,10 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) void (*func)(void *); void *arg; { - struct pte *pt; - struct pcb *nyproc; + struct pcb *pcb; struct trapframe *tf; - struct pmap *pmap, *opmap; + struct callsframe *cf; + extern int sret; /* Return address in trap routine */ #ifdef DIAGNOSTIC /* @@ -126,28 +126,46 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) panic("cpu_fork: curproc"); #endif - nyproc = &p2->p_addr->u_pcb; - tf = p1->p_addr->u_pcb.framep; - opmap = p1->p_vmspace->vm_map.pmap; - pmap = p2->p_vmspace->vm_map.pmap; - - /* Mark page invalid */ - pt = kvtopte((u_int)p2->p_addr + REDZONEADDR); - pt->pg_v = 0; + /* + * Copy the trap frame. + */ + tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1; + p2->p_addr->u_pcb.framep = tf; + bcopy(p1->p_addr->u_pcb.framep, tf, sizeof(*tf)); /* * Activate address space for the new process. The PTEs have * already been allocated by way of pmap_create(). + * This writes the page table registers to the PCB. */ pmap_activate(p2); - /* Set up internal defs in PCB. */ - nyproc->iftrap = NULL; - nyproc->KSP = (u_int)p2->p_addr + USPACE; + /* Mark guard page invalid in kernel stack */ + kvtopte((u_int)p2->p_addr + REDZONEADDR)->pg_v = 0; - /* General registers as taken from userspace */ - /* trapframe should be synced with pcb */ - bcopy(&tf->r2,&nyproc->R[2],10*sizeof(int)); + /* + * Set up the calls frame above (below) the trapframe + * and populate it with something good. + * This is so that we can simulate that we were called by a + * CALLS insn in the function given as argument. + */ + cf = (struct callsframe *)tf - 1; + cf->ca_cond = 0; + cf->ca_maskpsw = 0x20000000; /* CALLS stack frame, no registers */ + cf->ca_pc = (unsigned)&sret; /* return PC; userspace trampoline */ + cf->ca_argno = 1; + cf->ca_arg1 = (int)arg; + + /* + * Set up internal defs in PCB. This matches the "fake" CALLS frame + * that we constructed earlier. + */ + pcb = &p2->p_addr->u_pcb; + pcb->iftrap = NULL; + pcb->KSP = (long)cf; + pcb->FP = (long)cf; + pcb->AP = (long)&cf->ca_argno; + pcb->PC = (int)func + 2; /* Skip save mask */ /* * If specified, give the child a different stack. @@ -155,52 +173,9 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) if (stack != NULL) tf->sp = (u_long)stack + stacksize; - nyproc->AP = tf->ap; - nyproc->FP = tf->fp; - nyproc->USP = tf->sp; - nyproc->PC = tf->pc; - nyproc->PSL = tf->psl & ~PSL_C; - nyproc->R[0] = p1->p_pid; /* parent pid. (shouldn't be needed) */ - nyproc->R[1] = 1; - - return; /* Child is ready. Parent, return! */ -} - -/* - * cpu_set_kpc() sets up pcb for the new kernel process so that it will - * start at the procedure pointed to by pc next time swtch() is called. - * When that procedure returns, it will pop off everything from the - * faked calls frame on the kernel stack, do an REI and go down to - * user mode. - */ -void -cpu_set_kpc(p, pc, arg) - struct proc *p; - void (*pc) __P((void *)); - void *arg; -{ - struct pcb *nyproc; - struct { - struct callsframe cf; - struct trapframe tf; - } *kc; - extern int sret, boothowto; - - nyproc = &p->p_addr->u_pcb; - (unsigned)kc = nyproc->FP = nyproc->KSP = - (unsigned)p->p_addr + USPACE - sizeof(*kc); - kc->cf.ca_cond = 0; - kc->cf.ca_maskpsw = 0x20000000; - kc->cf.ca_pc = (unsigned)&sret; - kc->cf.ca_argno = 1; - kc->cf.ca_arg1 = (unsigned)arg; - kc->tf.r11 = boothowto; /* If we have old init */ - kc->tf.psl = 0x3c00000; - - nyproc->framep = (void *)&kc->tf; - nyproc->AP = (unsigned)&kc->cf.ca_argno; - nyproc->FP = nyproc->KSP = (unsigned)kc; - nyproc->PC = (unsigned)pc + 2; + tf->r0 = p1->p_pid; /* parent pid. (shouldn't be needed) */ + tf->r1 = 1; + tf->psl = PSL_U|PSL_PREVU; } int |