예제 #1
0
int thread_load(struct thread *thread) {
	
	if (thread->vm86_active) {
		set_int_stack(&thread->vm86_start);
	}
	else {
		set_int_stack(&thread->vm86_es);
	}

	if (thread->fxdata) {
		fpu_load(thread->fxdata);
	}

	if (thread->pctx && thread->pctx != _active_pctx) {
		pctx_load(thread->pctx);
	}

	_active_thread = thread;

	return 0;
}
예제 #2
0
void
setup_linux_rt_sigframe(struct trapframe *tf, const ksiginfo_t *ksi,
    const sigset_t *mask)
{
	struct lwp *l = curlwp;
	struct proc *p = l->l_proc;
	struct linux_rt_sigframe *sfp, sigframe;
	int onstack, error;
	int fsize, rndfsize;
	int sig = ksi->ksi_signo;
	extern char linux_rt_sigcode[], linux_rt_esigcode[];

	/* Do we need to jump onto the signal stack? */
	onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
		  (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;

	/* Allocate space for the signal handler context.  */
	fsize = sizeof(struct linux_rt_sigframe);
	rndfsize = ((fsize + 15) / 16) * 16;

	if (onstack)
		sfp = (struct linux_rt_sigframe *)
		    ((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size);
	else
		sfp = (struct linux_rt_sigframe *)(alpha_pal_rdusp());
	sfp = (struct linux_rt_sigframe *)((char *)sfp - rndfsize);

#ifdef DEBUG
	if ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid))
		printf("linux_sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid,
		    sig, &onstack, sfp);
#endif /* DEBUG */

	/*
	 * Build the signal context to be used by sigreturn.
	 */
	memset(&sigframe.uc, 0, sizeof(struct linux_ucontext));
	sigframe.uc.uc_mcontext.sc_onstack = onstack;

	/* Setup potentially partial signal mask in sc_mask. */
	/* But get all of it in uc_sigmask */
	native_to_linux_old_sigset(&sigframe.uc.uc_mcontext.sc_mask, mask);
	native_to_linux_sigset(&sigframe.uc.uc_sigmask, mask);

	sigframe.uc.uc_mcontext.sc_pc = tf->tf_regs[FRAME_PC];
	sigframe.uc.uc_mcontext.sc_ps = ALPHA_PSL_USERMODE;
	frametoreg(tf, (struct reg *)sigframe.uc.uc_mcontext.sc_regs);
	sigframe.uc.uc_mcontext.sc_regs[R_SP] = alpha_pal_rdusp();

	fpu_load();
	alpha_pal_wrfen(1);
	sigframe.uc.uc_mcontext.sc_fpcr = alpha_read_fpcr();
	sigframe.uc.uc_mcontext.sc_fp_control = alpha_read_fp_c(l);
	alpha_pal_wrfen(0);

	sigframe.uc.uc_mcontext.sc_traparg_a0 = tf->tf_regs[FRAME_A0];
	sigframe.uc.uc_mcontext.sc_traparg_a1 = tf->tf_regs[FRAME_A1];
	sigframe.uc.uc_mcontext.sc_traparg_a2 = tf->tf_regs[FRAME_A2];
	native_to_linux_siginfo(&sigframe.info, &ksi->ksi_info);
	sendsig_reset(l, sig);
	mutex_exit(p->p_lock);
	error = copyout((void *)&sigframe, (void *)sfp, fsize);
	mutex_enter(p->p_lock);

	if (error != 0) {
#ifdef DEBUG
		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
			printf("sendsig(%d): copyout failed on sig %d\n",
			    p->p_pid, sig);
#endif
		/*
		 * Process has trashed its stack; give it an illegal
		 * instruction to halt it in its tracks.
		 */
		sigexit(l, SIGILL);
		/* NOTREACHED */
	}

	/* Pass pointers to siginfo and ucontext in the regs */
	tf->tf_regs[FRAME_A1] = (unsigned long)&sfp->info;
	tf->tf_regs[FRAME_A2] = (unsigned long)&sfp->uc;

	/* Address of trampoline code.  End up at this PC after mi_switch */
	tf->tf_regs[FRAME_PC] =
	    (u_int64_t)(p->p_psstrp - (linux_rt_esigcode - linux_rt_sigcode));

	/* Adjust the stack */
	alpha_pal_wrusp((unsigned long)sfp);

	/* Remember that we're now on the signal stack. */
	if (onstack)
		l->l_sigstk.ss_flags |= SS_ONSTACK;
}