summaryrefslogtreecommitdiffstats
path: root/sys/i386/i386/vm_machdep.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2001-09-12 08:38:13 +0000
committerjulian <julian@FreeBSD.org>2001-09-12 08:38:13 +0000
commit5596676e6c6c1e81e899cd0531f9b1c28a292669 (patch)
treeb1a19fcdf05759281fab0d89efb13f0fdf42102e /sys/i386/i386/vm_machdep.c
parent83e00d4274950d2b531c24692cd123538ffbddb9 (diff)
downloadFreeBSD-src-5596676e6c6c1e81e899cd0531f9b1c28a292669.zip
FreeBSD-src-5596676e6c6c1e81e899cd0531f9b1c28a292669.tar.gz
KSE Milestone 2
Note ALL MODULES MUST BE RECOMPILED make the kernel aware that there are smaller units of scheduling than the process. (but only allow one thread per process at this time). This is functionally equivalent to teh previousl -current except that there is a thread associated with each process. Sorry john! (your next MFC will be a doosie!) Reviewed by: peter@freebsd.org, dillon@freebsd.org X-MFC after: ha ha ha ha
Diffstat (limited to 'sys/i386/i386/vm_machdep.c')
-rw-r--r--sys/i386/i386/vm_machdep.c79
1 files changed, 45 insertions, 34 deletions
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 53cedff..83ddc21 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -47,7 +47,7 @@
#endif
#include "opt_reset.h"
#include "opt_isa.h"
-#include "opt_upages.h"
+#include "opt_kstack_pages.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -117,19 +117,24 @@ vm_fault_quick(v, prot)
* ready to run and return to user mode.
*/
void
-cpu_fork(p1, p2, flags)
- register struct proc *p1, *p2;
+cpu_fork(td1, p2, flags)
+ register struct thread *td1;
+ register struct proc *p2;
int flags;
{
+ register struct proc *p1;
+ struct thread *td2;
struct pcb *pcb2;
#ifdef DEV_NPX
int savecrit;
#endif
+ p1 = td1->td_proc;
+ td2 = &p2->p_thread;
if ((flags & RFPROC) == 0) {
if ((flags & RFMEM) == 0) {
/* unshare user LDT */
- struct pcb *pcb1 = &p1->p_addr->u_pcb;
+ struct pcb *pcb1 = td1->td_pcb;
struct pcb_ldt *pcb_ldt = pcb1->pcb_ldt;
if (pcb_ldt && pcb_ldt->ldt_refcnt > 1) {
pcb_ldt = user_ldt_alloc(pcb1,pcb_ldt->ldt_len);
@@ -145,30 +150,32 @@ cpu_fork(p1, p2, flags)
/* Ensure that p1's pcb is up to date. */
#ifdef DEV_NPX
- if (p1 == curproc)
- p1->p_addr->u_pcb.pcb_gs = rgs();
+ if (td1 == curthread)
+ td1->td_pcb->pcb_gs = rgs();
savecrit = critical_enter();
- if (PCPU_GET(npxproc) == p1)
- npxsave(&p1->p_addr->u_pcb.pcb_save);
+ if (PCPU_GET(npxthread) == td1)
+ npxsave(&td1->td_pcb->pcb_save);
critical_exit(savecrit);
#endif
+ /* Point the pcb to the top of the stack */
+ pcb2 = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
+ td2->td_pcb = pcb2;
+
/* Copy p1's pcb. */
- p2->p_addr->u_pcb = p1->p_addr->u_pcb;
- pcb2 = &p2->p_addr->u_pcb;
+ bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
/*
* Create a new fresh stack for the new process.
* Copy the trap frame for the return to user mode as if from a
* syscall. This copies most of the user mode register values.
*/
- p2->p_frame = (struct trapframe *)
- ((int)p2->p_addr + UPAGES * PAGE_SIZE - 16) - 1;
- bcopy(p1->p_frame, p2->p_frame, sizeof(struct trapframe));
+ td2->td_frame = (struct trapframe *)td2->td_pcb - 1;
+ bcopy(td1->td_frame, td2->td_frame, sizeof(struct trapframe));
- p2->p_frame->tf_eax = 0; /* Child returns zero */
- p2->p_frame->tf_eflags &= ~PSL_C; /* success */
- p2->p_frame->tf_edx = 1;
+ td2->td_frame->tf_eax = 0; /* Child returns zero */
+ td2->td_frame->tf_eflags &= ~PSL_C; /* success */
+ td2->td_frame->tf_edx = 1;
/*
* Set registers for trampoline to user mode. Leave space for the
@@ -178,8 +185,8 @@ cpu_fork(p1, p2, flags)
pcb2->pcb_edi = 0;
pcb2->pcb_esi = (int)fork_return; /* fork_trampoline argument */
pcb2->pcb_ebp = 0;
- pcb2->pcb_esp = (int)p2->p_frame - sizeof(void *);
- pcb2->pcb_ebx = (int)p2; /* fork_trampoline argument */
+ pcb2->pcb_esp = (int)td2->td_frame - sizeof(void *);
+ pcb2->pcb_ebx = (int)td2; /* fork_trampoline argument */
pcb2->pcb_eip = (int)fork_trampoline;
/*-
* pcb2->pcb_dr*: cloned above.
@@ -228,8 +235,8 @@ cpu_fork(p1, p2, flags)
* This is needed to make kernel threads stay in kernel mode.
*/
void
-cpu_set_fork_handler(p, func, arg)
- struct proc *p;
+cpu_set_fork_handler(td, func, arg)
+ struct thread *td;
void (*func) __P((void *));
void *arg;
{
@@ -237,18 +244,18 @@ cpu_set_fork_handler(p, func, arg)
* Note that the trap frame follows the args, so the function
* is really called like this: func(arg, frame);
*/
- p->p_addr->u_pcb.pcb_esi = (int) func; /* function */
- p->p_addr->u_pcb.pcb_ebx = (int) arg; /* first arg */
+ td->td_pcb->pcb_esi = (int) func; /* function */
+ td->td_pcb->pcb_ebx = (int) arg; /* first arg */
}
void
-cpu_exit(p)
- register struct proc *p;
+cpu_exit(td)
+ register struct thread *td;
{
- struct pcb *pcb = &p->p_addr->u_pcb;
+ struct pcb *pcb = td->td_pcb;
#ifdef DEV_NPX
- npxexit(p);
+ npxexit(td);
#endif
if (pcb->pcb_ext != 0) {
/*
@@ -280,25 +287,29 @@ cpu_wait(p)
* Dump the machine specific header information at the start of a core dump.
*/
int
-cpu_coredump(p, vp, cred)
- struct proc *p;
+cpu_coredump(td, vp, cred)
+ struct thread *td;
struct vnode *vp;
struct ucred *cred;
{
+ struct proc *p = td->td_proc;
int error;
caddr_t tempuser;
- tempuser = malloc(ctob(UPAGES), M_TEMP, M_WAITOK | M_ZERO);
+ tempuser = malloc(ctob(UAREA_PAGES + KSTACK_PAGES), M_TEMP, M_WAITOK | M_ZERO);
if (!tempuser)
return EINVAL;
- bcopy(p->p_addr, tempuser, sizeof(struct user));
- bcopy(p->p_frame,
- tempuser + ((caddr_t) p->p_frame - (caddr_t) p->p_addr),
+ bcopy(p->p_uarea, tempuser, sizeof(struct user));
+#if 0 /* XXXKSE - broken, fixme!!!!! td_frame is in kstack! */
+ bcopy(td->td_frame,
+ tempuser + ((caddr_t) td->td_frame - (caddr_t) p->p_uarea),
sizeof(struct trapframe));
+#endif
- error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser, ctob(UPAGES),
- (off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, p);
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser,
+ ctob(UAREA_PAGES + KSTACK_PAGES),
+ (off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, td);
free(tempuser, M_TEMP);
OpenPOWER on IntegriCloud