Beispiel #1
0
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
			      user_regs_struct_t *regs,
			      user_fpregs_struct_t *fpregs)
{
	mcontext_t *dst_tc = &sigframe->uc_transact.uc_mcontext;
	mcontext_t *dst = &sigframe->uc.uc_mcontext;

	if (fpregs->flags & USER_FPREGS_FL_TM) {
		prep_gp_regs(&sigframe->uc_transact.uc_mcontext, &fpregs->tm.regs);
		prep_gp_regs(&sigframe->uc.uc_mcontext, &fpregs->tm.regs);
	} else {
		prep_gp_regs(&sigframe->uc.uc_mcontext, regs);
	}

	if (fpregs->flags & USER_FPREGS_FL_TM)
		sigframe->uc.uc_link = &sigframe->uc_transact;

	if (fpregs->flags & USER_FPREGS_FL_FP) {
		if (fpregs->flags & USER_FPREGS_FL_TM) {
			put_fpu_regs(&sigframe->uc_transact.uc_mcontext, fpregs->tm.fpregs);
			put_fpu_regs(&sigframe->uc.uc_mcontext, fpregs->tm.fpregs);
		} else {
			put_fpu_regs(&sigframe->uc.uc_mcontext, fpregs->fpregs);
		}
	}

	if (fpregs->flags & USER_FPREGS_FL_ALTIVEC) {
		if (fpregs->flags & USER_FPREGS_FL_TM) {
			put_altivec_regs(&sigframe->uc_transact.uc_mcontext, fpregs->tm.vrregs);
			put_altivec_regs(&sigframe->uc.uc_mcontext, fpregs->tm.vrregs);

			dst_tc->gp_regs[PT_MSR] |= MSR_VEC;
		} else {
			put_altivec_regs(&sigframe->uc.uc_mcontext, fpregs->vrregs);
		}

		dst->gp_regs[PT_MSR] |= MSR_VEC;

		if (fpregs->flags & USER_FPREGS_FL_VSX) {
			if (fpregs->flags & USER_FPREGS_FL_TM) {
				put_vsx_regs(&sigframe->uc_transact.uc_mcontext, fpregs->tm.vsxregs);
				put_vsx_regs(&sigframe->uc.uc_mcontext, fpregs->tm.vsxregs);

				dst_tc->gp_regs[PT_MSR] |= MSR_VSX;
			} else {
				put_vsx_regs(&sigframe->uc.uc_mcontext, fpregs->vsxregs);
			}
			dst->gp_regs[PT_MSR] |= MSR_VSX;
		}
	}

	return 0;
}
Beispiel #2
0
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
{
	int ret = 0;

	if (CORE_THREAD_ARCH_INFO(core)->fpstate)
		put_fpu_regs(&sigframe->uc.uc_mcontext,
			     CORE_THREAD_ARCH_INFO(core)->fpstate);

	if (CORE_THREAD_ARCH_INFO(core)->vrstate)
		ret = put_altivec_regs(&sigframe->uc.uc_mcontext,
				       CORE_THREAD_ARCH_INFO(core)->vrstate);
	else if (core->ti_ppc64->gpregs->msr & MSR_VEC) {
		pr_err("Register's data mismatch, corrupted image ?\n");
		ret = -1;
	}

	if (!ret && CORE_THREAD_ARCH_INFO(core)->vsxstate)
		ret = put_vsx_regs(&sigframe->uc.uc_mcontext,
				   CORE_THREAD_ARCH_INFO(core)->vsxstate);
	else if (core->ti_ppc64->gpregs->msr & MSR_VSX) {
		pr_err("VSX register's data mismatch, corrupted image ?\n");
		ret = -1;
	}

	if (!ret && CORE_THREAD_ARCH_INFO(core)->tmstate)
		ret = put_tm_regs(sigframe,
				  CORE_THREAD_ARCH_INFO(core)->tmstate);
	else if (MSR_TM_ACTIVE(core->ti_ppc64->gpregs->msr)) {
		pr_err("TM register's data mismatch, corrupted image ?\n");
		ret = -1;
	}

	return ret;
}
Beispiel #3
0
static int put_tm_regs(struct rt_sigframe *f, UserPpc64TmRegsEntry *tme)
{
/*
 * WARNING: As stated in kernel's restore_tm_sigcontexts, TEXASR has to be
 * restored by the process itself :
 *   TEXASR was set by the signal delivery reclaim, as was TFIAR.
 *   Users doing anything abhorrent like thread-switching w/ signals for
 *   TM-Suspended code will have to back TEXASR/TFIAR up themselves.
 *   For the case of getting a signal and simply returning from it,
 *   we don't need to re-copy them here.
 */
	ucontext_t *tm_uc = &f->uc_transact;

	pr_debug("Restoring TM registers FP:%d VR:%d VSX:%d\n",
		 !!(tme->fpstate), !!(tme->vrstate), !!(tme->vsxstate));

	restore_gp_regs(&tm_uc->uc_mcontext, tme->gpregs);

	if (tme->fpstate)
		put_fpu_regs(&tm_uc->uc_mcontext, tme->fpstate);

	if (tme->vrstate && put_altivec_regs(&tm_uc->uc_mcontext,
					     tme->vrstate))
		return -1;

	if (tme->vsxstate && put_vsx_regs(&tm_uc->uc_mcontext,
					  tme->vsxstate))
		return -1;

	f->uc.uc_link = tm_uc;
	return 0;
}
Beispiel #4
0
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
{
	int ret = 0;
	if (CORE_THREAD_ARCH_INFO(core)->fpstate)
		put_fpu_regs(&sigframe->uc.uc_mcontext,
			     CORE_THREAD_ARCH_INFO(core)->fpstate);

	if (CORE_THREAD_ARCH_INFO(core)->vrstate)
		ret = put_altivec_regs(&sigframe->uc.uc_mcontext,
				       CORE_THREAD_ARCH_INFO(core)->vrstate);
	else if (core->ti_ppc64->gpregs->msr & MSR_VEC) {
		pr_err("Internal error\n");
		ret = -1;
	}

	if (!ret && CORE_THREAD_ARCH_INFO(core)->vsxstate)
		ret = put_vsx_regs(&sigframe->uc.uc_mcontext,
				   CORE_THREAD_ARCH_INFO(core)->vsxstate);
	else if (core->ti_ppc64->gpregs->msr & MSR_VSX) {
		pr_err("Internal error\n");
		ret = -1;
	}

	return ret;
}