vm_machdep.c (24361) | vm_machdep.c (24691) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986 The Regents of the University of California. 3 * Copyright (c) 1989, 1990 William Jolitz 4 * Copyright (c) 1994 John Dyson 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer --- 24 unchanged lines hidden (view full) --- 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 40 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ | 1/*- 2 * Copyright (c) 1982, 1986 The Regents of the University of California. 3 * Copyright (c) 1989, 1990 William Jolitz 4 * Copyright (c) 1994 John Dyson 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer --- 24 unchanged lines hidden (view full) --- 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 40 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ |
41 * $Id: vm_machdep.c,v 1.76 1997/03/22 04:28:16 dyson Exp $ | 41 * $Id: vm_machdep.c,v 1.77 1997/03/29 04:35:26 bde Exp $ |
42 */ 43 44#include "npx.h" 45#include "opt_bounce.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/proc.h> 50#include <sys/malloc.h> 51#include <sys/buf.h> 52#include <sys/vnode.h> 53#include <sys/vmmeter.h> 54 55#include <machine/clock.h> 56#include <machine/md_var.h> | 42 */ 43 44#include "npx.h" 45#include "opt_bounce.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/proc.h> 50#include <sys/malloc.h> 51#include <sys/buf.h> 52#include <sys/vnode.h> 53#include <sys/vmmeter.h> 54 55#include <machine/clock.h> 56#include <machine/md_var.h> |
57#include <machine/cpu.h> 58#include <machine/reg.h> |
|
57 58#include <vm/vm.h> 59#include <vm/vm_param.h> 60#include <vm/vm_prot.h> 61#include <sys/lock.h> 62#include <vm/vm_kern.h> 63#include <vm/vm_page.h> 64#include <vm/vm_map.h> --- 488 unchanged lines hidden (view full) --- 553 if (prot & VM_PROT_WRITE) 554 subyte(v, fubyte(v)); 555 else 556 fubyte(v); 557} 558 559/* 560 * Finish a fork operation, with process p2 nearly set up. | 59 60#include <vm/vm.h> 61#include <vm/vm_param.h> 62#include <vm/vm_prot.h> 63#include <sys/lock.h> 64#include <vm/vm_kern.h> 65#include <vm/vm_page.h> 66#include <vm/vm_map.h> --- 488 unchanged lines hidden (view full) --- 555 if (prot & VM_PROT_WRITE) 556 subyte(v, fubyte(v)); 557 else 558 fubyte(v); 559} 560 561/* 562 * Finish a fork operation, with process p2 nearly set up. |
561 * Copy and update the kernel stack and pcb, making the child 562 * ready to run, and marking it so that it can return differently 563 * than the parent. Returns 1 in the child process, 0 in the parent. 564 * We currently double-map the user area so that the stack is at the same 565 * address in each process; in the future we will probably relocate 566 * the frame pointers on the stack after copying. | 563 * Copy and update the pcb, set up the stack so that the child 564 * ready to run and return to user mode. |
567 */ | 565 */ |
568int | 566void |
569cpu_fork(p1, p2) 570 register struct proc *p1, *p2; 571{ 572 struct pcb *pcb2 = &p2->p_addr->u_pcb; | 567cpu_fork(p1, p2) 568 register struct proc *p1, *p2; 569{ 570 struct pcb *pcb2 = &p2->p_addr->u_pcb; |
573 int sp, offset; 574 volatile int retval; 575#ifdef USER_LDT 576 struct pcb *pcb = &p2->p_addr->u_pcb; 577#endif | |
578 579 /* | 571 572 /* |
580 * Copy pcb and stack from proc p1 to p2. 581 * We do this as cheaply as possible, copying only the active 582 * part of the stack. The stack and pcb need to agree; 583 * this is tricky, as the final pcb is constructed by savectx, 584 * but its frame isn't yet on the stack when the stack is copied. 585 * This should be done differently, with a single call 586 * that copies and updates the pcb+stack, 587 * replacing the bcopy and savectx. | 573 * copy current pcb, and save current context into it while it's 574 * possibly in some writeback cache line. |
588 */ | 575 */ |
576 bcopy(&p1->p_addr->u_pcb, pcb2, sizeof(struct pcb)); 577 pcb2->pcb_cr3 = vtophys(p2->p_vmspace->vm_pmap.pm_pdir); 578 savectx(pcb2); /* irrelevant? fp registers? */ |
|
589 | 579 |
590 __asm __volatile("movl %%esp,%0" : "=r" (sp)); 591 offset = sp - (int)kstack; | 580 /* 581 * Create a new fresh stack for the new process. 582 * Copy the trap frame for the return to user mode as if from a syscall. 583 * This copies the user mode register values. 584 */ 585 p2->p_md.md_regs = (int *)(((struct trapframe *) 586 ((int)p2->p_addr + (UPAGES * PAGE_SIZE))) - 1); 587 bcopy(p1->p_md.md_regs, p2->p_md.md_regs, sizeof(struct trapframe)); |
592 | 588 |
593 retval = 1; /* return 1 in child */ 594 bcopy((caddr_t)kstack + offset, (caddr_t)p2->p_addr + offset, 595 (unsigned) ctob(UPAGES) - offset); 596 p2->p_md.md_regs = p1->p_md.md_regs; | 589 /* 590 * Set registers for trampoline to user mode. Leave space for the 591 * return address on stack. These are the kernel mode register values. 592 */ 593 /* XXX these overwrite most of the regs from savectx() above! */ 594 pcb2->pcb_eip = (int)fork_trampoline; 595 pcb2->pcb_esi = (int)fork_return; 596 pcb2->pcb_ebx = (int)p2; 597 pcb2->pcb_esp = (int)p2->p_md.md_regs - sizeof(void *); |
597 | 598 |
598 *pcb2 = p1->p_addr->u_pcb; 599 pcb2->pcb_cr3 = vtophys(p2->p_vmspace->vm_pmap.pm_pdir); 600 | |
601#ifdef USER_LDT 602 /* Copy the LDT, if necessary. */ | 599#ifdef USER_LDT 600 /* Copy the LDT, if necessary. */ |
603 if (pcb->pcb_ldt != 0) { | 601 if (pcb2->pcb_ldt != 0) { |
604 union descriptor *new_ldt; | 602 union descriptor *new_ldt; |
605 size_t len = pcb->pcb_ldt_len * sizeof(union descriptor); | 603 size_t len = pcb2->pcb_ldt_len * sizeof(union descriptor); |
606 607 new_ldt = (union descriptor *)kmem_alloc(kernel_map, len); | 604 605 new_ldt = (union descriptor *)kmem_alloc(kernel_map, len); |
608 bcopy(pcb->pcb_ldt, new_ldt, len); 609 pcb->pcb_ldt = (caddr_t)new_ldt; | 606 bcopy(pcb2->pcb_ldt, new_ldt, len); 607 pcb2->pcb_ldt = (caddr_t)new_ldt; |
610 } 611#endif 612 | 608 } 609#endif 610 |
613 retval = 0; /* return 0 in parent */ 614 savectx(pcb2); 615 return (retval); | 611 /* 612 * Now, cpu_switch() can schedule the new process. 613 * pcb_esp is loaded pointing to the cpu_switch() stack frame 614 * containing the return address when exiting cpu_switch. 615 * This will normally be to proc_trampoline(), which will have 616 * %ebx loaded with the new proc's pointer. proc_trampoline() 617 * will set up a stack to call fork_return(p, frame); to complete 618 * the return to user-mode. 619 */ |
616} 617 | 620} 621 |
622/* 623 * Intercept the return address from a freshly forked process that has NOT 624 * been scheduled yet. 625 * 626 * This is needed to make kernel threads stay in kernel mode. 627 */ |
|
618void | 628void |
629cpu_set_fork_handler(p, func, arg) 630 struct proc *p; 631 void (*func) __P((void *)); 632 void *arg; 633{ 634 /* 635 * Note that the trap frame follows the args, so the function 636 * is really called like this: func(arg, frame); 637 */ 638 p->p_addr->u_pcb.pcb_esi = (int) func; /* function */ 639 p->p_addr->u_pcb.pcb_ebx = (int) arg; /* first arg */ 640} 641 642void |
|
619cpu_exit(p) 620 register struct proc *p; 621{ 622#ifdef USER_LDT 623 struct pcb *pcb; 624#endif 625 626#if NNPX > 0 --- 271 unchanged lines hidden --- | 643cpu_exit(p) 644 register struct proc *p; 645{ 646#ifdef USER_LDT 647 struct pcb *pcb; 648#endif 649 650#if NNPX > 0 --- 271 unchanged lines hidden --- |