Cleanup in cpu_fork - remove use of curproc
Startup code now ensures proc0pcb is valid.
This commit is contained in:
parent
851d298eea
commit
4dbca7a672
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: vm_machdep.c,v 1.28 1995/05/24 21:08:44 gwr Exp $ */
|
/* $NetBSD: vm_machdep.c,v 1.29 1995/05/26 17:20:30 gwr Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Gordon W. Ross
|
* Copyright (c) 1994 Gordon W. Ross
|
||||||
|
@ -63,9 +63,8 @@
|
||||||
#include <machine/pmap.h>
|
#include <machine/pmap.h>
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
/* XXX - Put these in some header file? */
|
/* XXX - Put this in some header file? */
|
||||||
void cpu_set_kpc __P((struct proc *p, u_long func));
|
void cpu_set_kpc __P((struct proc *p, u_long func));
|
||||||
void child_return __P((struct proc *p));
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,25 +80,13 @@ cpu_fork(p1, p2)
|
||||||
register struct pcb *pcb2 = &p2->p_addr->u_pcb;
|
register struct pcb *pcb2 = &p2->p_addr->u_pcb;
|
||||||
register struct trapframe *p2tf;
|
register struct trapframe *p2tf;
|
||||||
register struct switchframe *p2sf;
|
register struct switchframe *p2sf;
|
||||||
extern void proc_do_uret();
|
extern void proc_do_uret(), child_return();
|
||||||
|
|
||||||
/* copy over the machdep part of struct proc */
|
/* copy over the machdep part of struct proc */
|
||||||
p2->p_md.md_flags = p1->p_md.md_flags;
|
p2->p_md.md_flags = p1->p_md.md_flags;
|
||||||
|
|
||||||
/*
|
/* Copy pcb from proc p1 to p2. */
|
||||||
* Copy pcb from proc p1 to p2.
|
bcopy(&p1->p_addr->u_pcb, pcb2, sizeof(*pcb2));
|
||||||
* XXX - Note, if we have never called cpu_switch()
|
|
||||||
* then our own pcb will not have been initialized.
|
|
||||||
* Make sure it is valid or the child will die in
|
|
||||||
* cpu_switch() when it loads the new sr value.
|
|
||||||
* (Accidently clears the supervisor bit...)
|
|
||||||
*
|
|
||||||
* We can just save our context into p2, based on
|
|
||||||
* the assumption that p1 == curproc (verify that).
|
|
||||||
*/
|
|
||||||
if (p1 != curproc) /* XXX */
|
|
||||||
panic("cpu_fork: bad p1");
|
|
||||||
savectx(pcb2);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our cpu_switch MUST always call PMAP_ACTIVATE on a
|
* Our cpu_switch MUST always call PMAP_ACTIVATE on a
|
||||||
|
@ -112,7 +99,8 @@ cpu_fork(p1, p2)
|
||||||
* Pick a stack pointer, leaving room for a trapframe;
|
* Pick a stack pointer, leaving room for a trapframe;
|
||||||
* copy trapframe from parent so return to user mode
|
* copy trapframe from parent so return to user mode
|
||||||
* will be to right address, with correct registers.
|
* will be to right address, with correct registers.
|
||||||
* Leave one word at the end just to be like proc0...
|
* Leave one word unused at the end of the kernel stack
|
||||||
|
* so the system stack pointer stays within its stack.
|
||||||
*/
|
*/
|
||||||
p2tf = (struct trapframe *)((char*)p2->p_addr + USPACE-4) - 1;
|
p2tf = (struct trapframe *)((char*)p2->p_addr + USPACE-4) - 1;
|
||||||
p2->p_md.md_regs = (int *)p2tf;
|
p2->p_md.md_regs = (int *)p2tf;
|
||||||
|
@ -126,16 +114,13 @@ cpu_fork(p1, p2)
|
||||||
p2sf->sf_pc = (u_int)proc_do_uret;
|
p2sf->sf_pc = (u_int)proc_do_uret;
|
||||||
pcb2->pcb_regs[11] = (int)p2sf; /* SSP */
|
pcb2->pcb_regs[11] = (int)p2sf; /* SSP */
|
||||||
|
|
||||||
#if 1 /* XXX - Which way is better? */
|
|
||||||
cpu_set_kpc(p2, (long)child_return);
|
|
||||||
#else
|
|
||||||
/*
|
/*
|
||||||
* Set up return-value registers as fork() libc stub expects.
|
* 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().
|
||||||
*/
|
*/
|
||||||
p2tf->tf_regs[D0] = 0;
|
cpu_set_kpc(p2, (long)child_return);
|
||||||
p2tf->tf_sr &= ~PSL_C;
|
|
||||||
p2tf->tf_format = FMT0;
|
|
||||||
#endif
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +134,7 @@ cpu_fork(p1, p2)
|
||||||
* Note that it's assumed that when the named process returns,
|
* Note that it's assumed that when the named process returns,
|
||||||
* rei() should be invoked, to return to user mode. That is
|
* rei() should be invoked, to return to user mode. That is
|
||||||
* accomplished by having cpu_fork set the initial frame with a
|
* accomplished by having cpu_fork set the initial frame with a
|
||||||
* return address pointing to rei() which eventually does an rte.
|
* return address pointing to proc_do_uret() which does the rte.
|
||||||
*
|
*
|
||||||
* The design allows this function to be implemented as a general
|
* The design allows this function to be implemented as a general
|
||||||
* "kernel sendsig" utility, that can "push" a call to a kernel
|
* "kernel sendsig" utility, that can "push" a call to a kernel
|
||||||
|
@ -174,11 +159,6 @@ cpu_set_kpc(proc, func)
|
||||||
void *proc;
|
void *proc;
|
||||||
} *ksfp;
|
} *ksfp;
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
|
||||||
if (proc == curproc)
|
|
||||||
panic("cpu_set_kpc self");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pcbp = &proc->p_addr->u_pcb;
|
pcbp = &proc->p_addr->u_pcb;
|
||||||
|
|
||||||
/* Push a ksig frame onto the kernel stack. */
|
/* Push a ksig frame onto the kernel stack. */
|
||||||
|
|
Loading…
Reference in New Issue