Changeset View
Changeset View
Standalone View
Standalone View
sys/i386/i386/vm_machdep.c
Show First 20 Lines • Show All 211 Lines • ▼ Show 20 Lines | cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) | ||||
/* Point mdproc and then copy over td1's contents */ | /* Point mdproc and then copy over td1's contents */ | ||||
mdp2 = &p2->p_md; | mdp2 = &p2->p_md; | ||||
bcopy(&p1->p_md, mdp2, sizeof(*mdp2)); | bcopy(&p1->p_md, mdp2, sizeof(*mdp2)); | ||||
/* | /* | ||||
* Create a new fresh stack for the new process. | * Create a new fresh stack for the new process. | ||||
* Copy the trap frame for the return to user mode as if from a | * Copy the trap frame for the return to user mode as if from a | ||||
* syscall. This copies most of the user mode register values. | * syscall. This copies most of the user mode register values. | ||||
* The -16 is so we can expand the trapframe if we go to vm86. | * The -VM86_STACK_SPACE (-16) is so we can expand the trapframe | ||||
* if we go to vm86. | |||||
*/ | */ | ||||
td2->td_frame = (struct trapframe *)((caddr_t)td2->td_pcb - 16) - 1; | td2->td_frame = (struct trapframe *)((caddr_t)td2->td_pcb - | ||||
VM86_STACK_SPACE) - 1; | |||||
bcopy(td1->td_frame, td2->td_frame, sizeof(struct trapframe)); | bcopy(td1->td_frame, td2->td_frame, sizeof(struct trapframe)); | ||||
td2->td_frame->tf_eax = 0; /* Child returns zero */ | td2->td_frame->tf_eax = 0; /* Child returns zero */ | ||||
td2->td_frame->tf_eflags &= ~PSL_C; /* success */ | td2->td_frame->tf_eflags &= ~PSL_C; /* success */ | ||||
td2->td_frame->tf_edx = 1; | td2->td_frame->tf_edx = 1; | ||||
/* | /* | ||||
* If the parent process has the trap bit set (i.e. a debugger had | * If the parent process has the trap bit set (i.e. a debugger had | ||||
Show All 15 Lines | |||||
#else | #else | ||||
pcb2->pcb_cr3 = vtophys(vmspace_pmap(p2->p_vmspace)->pm_pdir); | pcb2->pcb_cr3 = vtophys(vmspace_pmap(p2->p_vmspace)->pm_pdir); | ||||
#endif | #endif | ||||
pcb2->pcb_edi = 0; | pcb2->pcb_edi = 0; | ||||
pcb2->pcb_esi = (int)fork_return; /* fork_trampoline argument */ | pcb2->pcb_esi = (int)fork_return; /* fork_trampoline argument */ | ||||
pcb2->pcb_ebp = 0; | pcb2->pcb_ebp = 0; | ||||
pcb2->pcb_esp = (int)td2->td_frame - sizeof(void *); | pcb2->pcb_esp = (int)td2->td_frame - sizeof(void *); | ||||
pcb2->pcb_ebx = (int)td2; /* fork_trampoline argument */ | pcb2->pcb_ebx = (int)td2; /* fork_trampoline argument */ | ||||
pcb2->pcb_eip = (int)fork_trampoline; | pcb2->pcb_eip = (int)fork_trampoline + setidt_disp; | ||||
/*- | /*- | ||||
* pcb2->pcb_dr*: cloned above. | * pcb2->pcb_dr*: cloned above. | ||||
* pcb2->pcb_savefpu: cloned above. | * pcb2->pcb_savefpu: cloned above. | ||||
* pcb2->pcb_flags: cloned above. | * pcb2->pcb_flags: cloned above. | ||||
* pcb2->pcb_onfault: cloned above (always NULL here?). | * pcb2->pcb_onfault: cloned above (always NULL here?). | ||||
* pcb2->pcb_gs: cloned above. | * pcb2->pcb_gs: cloned above. | ||||
* pcb2->pcb_ext: cleared below. | * pcb2->pcb_ext: cleared below. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | cpu_thread_clean(struct thread *td) | ||||
pcb = td->td_pcb; | pcb = td->td_pcb; | ||||
if (pcb->pcb_ext != NULL) { | if (pcb->pcb_ext != NULL) { | ||||
/* if (pcb->pcb_ext->ext_refcount-- == 1) ?? */ | /* if (pcb->pcb_ext->ext_refcount-- == 1) ?? */ | ||||
/* | /* | ||||
* XXX do we need to move the TSS off the allocated pages | * XXX do we need to move the TSS off the allocated pages | ||||
* before freeing them? (not done here) | * before freeing them? (not done here) | ||||
*/ | */ | ||||
kmem_free(kernel_arena, (vm_offset_t)pcb->pcb_ext, | pmap_trm_free(pcb->pcb_ext, ctob(IOPAGES + 1)); | ||||
ctob(IOPAGES + 1)); | |||||
pcb->pcb_ext = NULL; | pcb->pcb_ext = NULL; | ||||
} | } | ||||
} | } | ||||
void | void | ||||
cpu_thread_swapin(struct thread *td) | cpu_thread_swapin(struct thread *td) | ||||
{ | { | ||||
} | } | ||||
void | void | ||||
cpu_thread_swapout(struct thread *td) | cpu_thread_swapout(struct thread *td) | ||||
{ | { | ||||
} | } | ||||
void | void | ||||
cpu_thread_alloc(struct thread *td) | cpu_thread_alloc(struct thread *td) | ||||
{ | { | ||||
struct pcb *pcb; | struct pcb *pcb; | ||||
struct xstate_hdr *xhdr; | struct xstate_hdr *xhdr; | ||||
td->td_pcb = pcb = get_pcb_td(td); | td->td_pcb = pcb = get_pcb_td(td); | ||||
td->td_frame = (struct trapframe *)((caddr_t)pcb - 16) - 1; | td->td_frame = (struct trapframe *)((caddr_t)pcb - | ||||
VM86_STACK_SPACE) - 1; | |||||
pcb->pcb_ext = NULL; | pcb->pcb_ext = NULL; | ||||
pcb->pcb_save = get_pcb_user_save_pcb(pcb); | pcb->pcb_save = get_pcb_user_save_pcb(pcb); | ||||
if (use_xsave) { | if (use_xsave) { | ||||
xhdr = (struct xstate_hdr *)(pcb->pcb_save + 1); | xhdr = (struct xstate_hdr *)(pcb->pcb_save + 1); | ||||
bzero(xhdr, sizeof(*xhdr)); | bzero(xhdr, sizeof(*xhdr)); | ||||
xhdr->xstate_bv = xsave_mask; | xhdr->xstate_bv = xsave_mask; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | cpu_copy_thread(struct thread *td, struct thread *td0) | ||||
* Set registers for trampoline to user mode. Leave space for the | * Set registers for trampoline to user mode. Leave space for the | ||||
* return address on stack. These are the kernel mode register values. | * return address on stack. These are the kernel mode register values. | ||||
*/ | */ | ||||
pcb2->pcb_edi = 0; | pcb2->pcb_edi = 0; | ||||
pcb2->pcb_esi = (int)fork_return; /* trampoline arg */ | pcb2->pcb_esi = (int)fork_return; /* trampoline arg */ | ||||
pcb2->pcb_ebp = 0; | pcb2->pcb_ebp = 0; | ||||
pcb2->pcb_esp = (int)td->td_frame - sizeof(void *); /* trampoline arg */ | pcb2->pcb_esp = (int)td->td_frame - sizeof(void *); /* trampoline arg */ | ||||
pcb2->pcb_ebx = (int)td; /* trampoline arg */ | pcb2->pcb_ebx = (int)td; /* trampoline arg */ | ||||
pcb2->pcb_eip = (int)fork_trampoline; | pcb2->pcb_eip = (int)fork_trampoline + setidt_disp; | ||||
pcb2->pcb_gs = rgs(); | pcb2->pcb_gs = rgs(); | ||||
/* | /* | ||||
* If we didn't copy the pcb, we'd need to do the following registers: | * If we didn't copy the pcb, we'd need to do the following registers: | ||||
* pcb2->pcb_cr3: cloned above. | * pcb2->pcb_cr3: cloned above. | ||||
* pcb2->pcb_dr*: cloned above. | * pcb2->pcb_dr*: cloned above. | ||||
* pcb2->pcb_savefpu: cloned above. | * pcb2->pcb_savefpu: cloned above. | ||||
* pcb2->pcb_flags: cloned above. | * pcb2->pcb_flags: cloned above. | ||||
* pcb2->pcb_onfault: cloned above (always NULL here?). | * pcb2->pcb_onfault: cloned above (always NULL here?). | ||||
▲ Show 20 Lines • Show All 240 Lines • ▼ Show 20 Lines | sf_buf_map(struct sf_buf *sf, int flags) | ||||
* Update the sf_buf's virtual-to-physical mapping, flushing the | * Update the sf_buf's virtual-to-physical mapping, flushing the | ||||
* virtual address from the TLB. Since the reference count for | * virtual address from the TLB. Since the reference count for | ||||
* the sf_buf's old mapping was zero, that mapping is not | * the sf_buf's old mapping was zero, that mapping is not | ||||
* currently in use. Consequently, there is no need to exchange | * currently in use. Consequently, there is no need to exchange | ||||
* the old and new PTEs atomically, even under PAE. | * the old and new PTEs atomically, even under PAE. | ||||
*/ | */ | ||||
ptep = vtopte(sf->kva); | ptep = vtopte(sf->kva); | ||||
opte = *ptep; | opte = *ptep; | ||||
*ptep = VM_PAGE_TO_PHYS(sf->m) | pgeflag | PG_RW | PG_V | | *ptep = VM_PAGE_TO_PHYS(sf->m) | PG_RW | PG_V | | ||||
pmap_cache_bits(sf->m->md.pat_mode, 0); | pmap_cache_bits(sf->m->md.pat_mode, 0); | ||||
/* | /* | ||||
* Avoid unnecessary TLB invalidations: If the sf_buf's old | * Avoid unnecessary TLB invalidations: If the sf_buf's old | ||||
* virtual-to-physical mapping was not used, then any processor | * virtual-to-physical mapping was not used, then any processor | ||||
* that has invalidated the sf_buf's virtual address from its TLB | * that has invalidated the sf_buf's virtual address from its TLB | ||||
* since the last used mapping need not invalidate again. | * since the last used mapping need not invalidate again. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 107 Lines • Show Last 20 Lines |