summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1997-05-07 20:19:18 +0000
committerpeter <peter@FreeBSD.org>1997-05-07 20:19:18 +0000
commit27b2936ad3bbcfef8e9dbe7ce4ee35b3fca07436 (patch)
tree4b4b12317a3b5a392dd36a7a5bd1dcb08ea64e05 /sys
parent2a925f680350c68481e736fc208bbe2dfc61d836 (diff)
downloadFreeBSD-src-27b2936ad3bbcfef8e9dbe7ce4ee35b3fca07436.zip
FreeBSD-src-27b2936ad3bbcfef8e9dbe7ce4ee35b3fca07436.tar.gz
clean up forked child creation. This is simplified also by having
md_regs being struct trapframe *. Do a npxsave() if needed and copy the pcb rather than use the increasingly defunct savectx(). Copy %edi and %ebp explicitly. Submitted by: bde XXX npxproc could be declared in npx.h so the externs with smp fruit are not needed.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/vm_machdep.c53
-rw-r--r--sys/i386/i386/vm_machdep.c53
2 files changed, 72 insertions, 34 deletions
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 37fa090..6f1a4b6 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.78 1997/04/07 07:15:56 peter Exp $
+ * $Id: vm_machdep.c,v 1.79 1997/04/16 12:11:37 kato Exp $
*/
#include "npx.h"
@@ -53,9 +53,13 @@
#include <sys/vmmeter.h>
#include <machine/clock.h>
-#include <machine/md_var.h>
#include <machine/cpu.h>
#include <machine/reg.h>
+#include <machine/md_var.h>
+#include <machine/npx.h>
+#ifdef SMP
+#include <machine/smp.h>
+#endif
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -74,6 +78,13 @@
#include <i386/isa/isa.h>
#endif
+#ifdef SMP
+extern struct proc *SMPnpxproc[];
+#define npxproc (SMPnpxproc[cpunumber()])
+#else
+extern struct proc *npxproc;
+#endif
+
#ifdef BOUNCE_BUFFERS
static vm_offset_t
vm_bounce_kva __P((int size, int waitok));
@@ -569,32 +580,40 @@ cpu_fork(p1, p2)
{
struct pcb *pcb2 = &p2->p_addr->u_pcb;
- /*
- * copy current pcb, and save current context into it while it's
- * possibly in some writeback cache line.
- */
- bcopy(&p1->p_addr->u_pcb, pcb2, sizeof(struct pcb));
- pcb2->pcb_cr3 = vtophys(p2->p_vmspace->vm_pmap.pm_pdir);
- savectx(pcb2); /* irrelevant? fp registers? */
+ /* Ensure that p1's pcb is up to date. */
+ if (npxproc == p1)
+ npxsave(&p1->p_addr->u_pcb.pcb_savefpu);
+
+ /* Copy p1's pcb. */
+ p2->p_addr->u_pcb = p1->p_addr->u_pcb;
/*
* 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 the user mode register values.
+ * Copy the trap frame for the return to user mode as if from a
+ * syscall. This copies the user mode register values.
*/
- p2->p_md.md_regs = (int *)(((struct trapframe *)
- ((int)p2->p_addr + (UPAGES * PAGE_SIZE))) - 1);
- bcopy(p1->p_md.md_regs, p2->p_md.md_regs, sizeof(struct trapframe));
+ p2->p_md.md_regs = (struct trapframe *)
+ ((int)p2->p_addr + UPAGES * PAGE_SIZE) - 1;
+ *p2->p_md.md_regs = *p1->p_md.md_regs;
/*
* Set registers for trampoline to user mode. Leave space for the
* return address on stack. These are the kernel mode register values.
*/
- /* XXX these overwrite most of the regs from savectx() above! */
- pcb2->pcb_eip = (int)fork_trampoline;
+ pcb2->pcb_cr3 = vtophys(p2->p_vmspace->vm_pmap.pm_pdir);
+ pcb2->pcb_edi = p2->p_md.md_regs->tf_edi;
pcb2->pcb_esi = (int)fork_return;
- pcb2->pcb_ebx = (int)p2;
+ pcb2->pcb_ebp = p2->p_md.md_regs->tf_ebp;
pcb2->pcb_esp = (int)p2->p_md.md_regs - sizeof(void *);
+ pcb2->pcb_ebx = (int)p2;
+ pcb2->pcb_eip = (int)fork_trampoline;
+ /*
+ * pcb2->pcb_ldt: duplicated below, if necessary.
+ * pcb2->pcb_ldt_len: cloned above.
+ * pcb2->pcb_savefpu: cloned above.
+ * pcb2->pcb_flags: cloned above (always 0 here?).
+ * pcb2->pcb_onfault: cloned above (always NULL here?).
+ */
#ifdef USER_LDT
/* Copy the LDT, if necessary. */
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 37fa090..6f1a4b6 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.78 1997/04/07 07:15:56 peter Exp $
+ * $Id: vm_machdep.c,v 1.79 1997/04/16 12:11:37 kato Exp $
*/
#include "npx.h"
@@ -53,9 +53,13 @@
#include <sys/vmmeter.h>
#include <machine/clock.h>
-#include <machine/md_var.h>
#include <machine/cpu.h>
#include <machine/reg.h>
+#include <machine/md_var.h>
+#include <machine/npx.h>
+#ifdef SMP
+#include <machine/smp.h>
+#endif
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -74,6 +78,13 @@
#include <i386/isa/isa.h>
#endif
+#ifdef SMP
+extern struct proc *SMPnpxproc[];
+#define npxproc (SMPnpxproc[cpunumber()])
+#else
+extern struct proc *npxproc;
+#endif
+
#ifdef BOUNCE_BUFFERS
static vm_offset_t
vm_bounce_kva __P((int size, int waitok));
@@ -569,32 +580,40 @@ cpu_fork(p1, p2)
{
struct pcb *pcb2 = &p2->p_addr->u_pcb;
- /*
- * copy current pcb, and save current context into it while it's
- * possibly in some writeback cache line.
- */
- bcopy(&p1->p_addr->u_pcb, pcb2, sizeof(struct pcb));
- pcb2->pcb_cr3 = vtophys(p2->p_vmspace->vm_pmap.pm_pdir);
- savectx(pcb2); /* irrelevant? fp registers? */
+ /* Ensure that p1's pcb is up to date. */
+ if (npxproc == p1)
+ npxsave(&p1->p_addr->u_pcb.pcb_savefpu);
+
+ /* Copy p1's pcb. */
+ p2->p_addr->u_pcb = p1->p_addr->u_pcb;
/*
* 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 the user mode register values.
+ * Copy the trap frame for the return to user mode as if from a
+ * syscall. This copies the user mode register values.
*/
- p2->p_md.md_regs = (int *)(((struct trapframe *)
- ((int)p2->p_addr + (UPAGES * PAGE_SIZE))) - 1);
- bcopy(p1->p_md.md_regs, p2->p_md.md_regs, sizeof(struct trapframe));
+ p2->p_md.md_regs = (struct trapframe *)
+ ((int)p2->p_addr + UPAGES * PAGE_SIZE) - 1;
+ *p2->p_md.md_regs = *p1->p_md.md_regs;
/*
* Set registers for trampoline to user mode. Leave space for the
* return address on stack. These are the kernel mode register values.
*/
- /* XXX these overwrite most of the regs from savectx() above! */
- pcb2->pcb_eip = (int)fork_trampoline;
+ pcb2->pcb_cr3 = vtophys(p2->p_vmspace->vm_pmap.pm_pdir);
+ pcb2->pcb_edi = p2->p_md.md_regs->tf_edi;
pcb2->pcb_esi = (int)fork_return;
- pcb2->pcb_ebx = (int)p2;
+ pcb2->pcb_ebp = p2->p_md.md_regs->tf_ebp;
pcb2->pcb_esp = (int)p2->p_md.md_regs - sizeof(void *);
+ pcb2->pcb_ebx = (int)p2;
+ pcb2->pcb_eip = (int)fork_trampoline;
+ /*
+ * pcb2->pcb_ldt: duplicated below, if necessary.
+ * pcb2->pcb_ldt_len: cloned above.
+ * pcb2->pcb_savefpu: cloned above.
+ * pcb2->pcb_flags: cloned above (always 0 here?).
+ * pcb2->pcb_onfault: cloned above (always NULL here?).
+ */
#ifdef USER_LDT
/* Copy the LDT, if necessary. */
OpenPOWER on IntegriCloud