/* * The memory maps have changed for up. Flush all cached state. */ void flushmmu(void) { if(tracemmu) iprint("flushmmu\n"); if(up) { vxproc_flush(up->pmmu.vxproc); mmapflush(up->pmmu.us); } }
/* * Called when proc p is dying. */ void mmurelease(Proc *p) { if(p->kp) return; if(tracemmu) iprint("mmurelease %ld %s\n", p->pid, p->text); if(p->pmmu.vxproc) vxproc_flush(p->pmmu.vxproc); if(p->pmmu.us) { if(tracemmu) iprint("^^^^^^^^^^ %ld %s [release %d]\n", p->pid, p->text, p->pmmu.us - uspace); putspace(p->pmmu.us); if(m->flushmmu) mmapflush(p->pmmu.us); } }
void touser(void *initsp) { int rc; void *kp; vxproc *vp; Ureg u; Ureg *u1; uchar *addr; vp = up->pmmu.vxproc; if(initsp){ /* init: clear register set, setup sp, eip */ memset(vp->cpu, 0, sizeof *vp->cpu); vp->cpu->reg[ESP] = (ulong)initsp; vp->cpu->eflags = 0; vp->cpu->eip = UTZERO+32; }else{ /* anyone else: registers are sitting at top of kernel stack */ kp = (char*)up->kstack + KSTACK - (sizeof(Ureg) + 2*BY2WD); u1 = (Ureg*)((char*)kp + 2*BY2WD); ureg2proc(u1, vp); } /* * User-mode execution loop. */ for(;;){ /* * Optimization: try to fault in code page and stack * page right now, since we're likely to need them. */ if(up->pmmu.us->hi == 0){ fault(vp->cpu->eip, 1); fault(vp->cpu->reg[ESP], 0); } /* * Let vx32 know whether to allow floating point. * TODO: Fix vx32 so that you don't need to flush * on the transition from FPinactive -> FPactive. */ if(vp->allowfp != (up->fpstate == FPactive)){ vp->allowfp = (up->fpstate == FPactive); vxproc_flush(vp); } if(traceprocs) iprint("+vx32 %p %p %s eip=%lux esp=%lux\n", m, up, up->text, vp->cpu->eip, vp->cpu->reg[ESP]); setsigsegv(1); setclock(1); rc = vxproc_run(vp); setclock(0); setsigsegv(0); if(rc < 0) panic("vxproc_run: %r"); if(traceprocs) iprint("-vx32 %p %p %s eip=%lux esp=%lux rc=%#x\n", m, up, up->text, vp->cpu->eip, vp->cpu->reg[ESP], rc); /* * Handle page faults quickly, without proc2ureg, ureg2proc, * if possible. Otherwise fall back to default trap call. */ if(rc == VXTRAP_PAGEFAULT){ int read; nfaults++; read = !(vp->cpu->traperr & 2); addr = (uchar*)(uintptr)vp->cpu->trapva; if(traceprocs) print("fault %p read=%d\n", addr, read); if(isuaddr(addr) && fault(addr - up->pmmu.uzero, read) >= 0) continue; print("%ld %s: unhandled fault va=%lux [%lux] eip=%lux\n", up->pid, up->text, addr - up->pmmu.uzero, vp->cpu->trapva, vp->cpu->eip); proc2ureg(vp, &u); dumpregs(&u); if(abortonfault) abort(); } up->dbgreg = &u; proc2ureg(vp, &u); u.trap = rc; trap(&u); ureg2proc(&u, vp); } }