void userret(struct lwp *l) { #if defined(__PROG32) && defined(ARM_MMU_EXTENDED) /* * If our ASID got released, access via TTBR0 will have been disabled. * So if it is disabled, activate the lwp again to get a new ASID. */ #ifdef __HAVE_PREEMPTION kpreempt_disable(); #endif KASSERT(curcpu()->ci_pmap_cur == l->l_proc->p_vmspace->vm_map.pmap); if (__predict_false(armreg_ttbcr_read() & TTBCR_S_PD0)) { pmap_activate(l); } KASSERT(!(armreg_ttbcr_read() & TTBCR_S_PD0)); #ifdef __HAVE_PREEMPTION kpreempt_enable(); #endif #endif /* Invoke MI userret code */ mi_userret(l); #if defined(__PROG32) && defined(DIAGNOSTIC) KASSERT(VALID_R15_PSR(lwp_trapframe(l)->tf_pc, lwp_trapframe(l)->tf_spsr)); #endif }
/* * trap and syscall both need the following work done before returning * to user mode. */ static inline void userret(struct lwp *l, struct frame *fp, u_quad_t oticks, u_int faultaddr, int fromtrap) { struct proc *p = l->l_proc; #ifdef M68040 int sig; int beenhere = 0; again: #endif /* Invoke MI userret code */ mi_userret(l); /* * If profiling, charge system time to the trapped pc. */ if (p->p_stflag & PST_PROFIL) { extern int psratio; addupc_task(l, fp->f_pc, (int)(p->p_sticks - oticks) * psratio); } #ifdef M68040 /* * Deal with user mode writebacks (from trap, or from sigreturn). * If any writeback fails, go back and attempt signal delivery. * unless we have already been here and attempted the writeback * (e.g. bad address with user ignoring SIGSEGV). In that case * we just return to the user without successfully completing * the writebacks. Maybe we should just drop the sucker? */ if ( #if defined(M68030) || defined(M68060) cputype == CPU_68040 && #endif fp->f_format == FMT7) { if (beenhere) { #ifdef DEBUG if (mmudebug & MDB_WBFAILED) printf(fromtrap ? "pid %d(%s): writeback aborted, pc=%x, fa=%x\n" : "pid %d(%s): writeback aborted in sigreturn, pc=%x\n", p->p_pid, p->p_comm, fp->f_pc, faultaddr); #endif } else if ((sig = writeback(fp, fromtrap))) { ksiginfo_t ksi; beenhere = 1; oticks = p->p_sticks; (void)memset(&ksi, 0, sizeof(ksi)); ksi.ksi_signo = sig; ksi.ksi_addr = (void *)faultaddr; ksi.ksi_code = BUS_OBJERR; trapsignal(l, &ksi); goto again; } } #endif }
/* * trap and syscall both need the following work done before * returning to user mode. */ static void userret(struct lwp *l, struct trapframe *tf, u_quad_t oticks) { struct proc *p = l->l_proc; /* Invoke MI userret code */ mi_userret(l); /* * If profiling, charge system time to the trapped pc. */ if (p->p_stflag & PST_PROFIL) { extern int psratio; addupc_task(l, tf->tf_pc, (int)(p->p_sticks - oticks) * psratio); } }