Exemplo n.º 1
0
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
}
Exemplo n.º 2
0
/*
 * 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
}
Exemplo n.º 3
0
/*
 * 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);
	}
}