Пример #1
0
/*
 * sigcontext handlers
 */
static int protected_save_fp_context32(struct sigcontext32 __user *sc,
				       unsigned used_math)
{
	int err;
	bool save_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
	while (1) {
		lock_fpu_owner();
		if (is_fpu_owner()) {
			err = save_fp_context32(sc);
			if (save_msa && !err)
				err = _save_msa_context32(sc);
			unlock_fpu_owner();
		} else {
			unlock_fpu_owner();
			err = copy_fp_to_sigcontext32(sc);
			if (save_msa && !err)
				err = copy_msa_to_sigcontext32(sc);
		}
		if (likely(!err))
			break;
		/* touch the sigcontext and try again */
		err = __put_user(0, &sc->sc_fpregs[0]) |
			__put_user(0, &sc->sc_fpregs[31]) |
			__put_user(0, &sc->sc_fpc_csr);
		if (err)
			break;	/* really bad sigcontext */
	}
	return err;
}
Пример #2
0
static inline int setup_sigcontext32(struct pt_regs *regs,
				     struct sigcontext32 __user *sc)
{
	int err = 0;

	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
	err |= __put_user(regs->cp0_status, &sc->sc_status);

#define save_gp_reg(i) {						\
	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
} while(0)
	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
	save_gp_reg(31);
#undef save_gp_reg

	err |= __put_user(regs->hi, &sc->sc_mdhi);
	err |= __put_user(regs->lo, &sc->sc_mdlo);
	if (cpu_has_dsp) {
		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
		err |= __put_user(mfhi1(), &sc->sc_hi1);
		err |= __put_user(mflo1(), &sc->sc_lo1);
		err |= __put_user(mfhi2(), &sc->sc_hi2);
		err |= __put_user(mflo2(), &sc->sc_lo2);
		err |= __put_user(mfhi3(), &sc->sc_hi3);
		err |= __put_user(mflo3(), &sc->sc_lo3);
	}

	err |= __put_user(!!used_math(), &sc->sc_used_math);

	if (!used_math())
		goto out;

	/*
	 * Save FPU state to signal context.  Signal handler will "inherit"
	 * current FPU state.
	 */
	preempt_disable();

	if (!is_fpu_owner()) {
		own_fpu();
		restore_fp(current);
	}
	err |= save_fp_context32(sc);

	preempt_enable();

out:
	return err;
}
/*
 * sigcontext handlers
 */
static int protected_save_fp_context32(struct sigcontext32 __user *sc)
{
	int err;
	while (1) {
		lock_fpu_owner();
		own_fpu_inatomic(1);
		err = save_fp_context32(sc); /* this might fail */
		unlock_fpu_owner();
		if (likely(!err))
			break;
		/* touch the sigcontext and try again */
		err = __put_user(0, &sc->sc_fpregs[0]) |
			__put_user(0, &sc->sc_fpregs[31]) |
			__put_user(0, &sc->sc_fpc_csr);
		if (err)
			break;	/* really bad sigcontext */
	}
	return err;
}
/*
 * sigcontext handlers
 */
static int protected_save_fp_context32(struct sigcontext32 __user *sc)
{
	int err;
	while (1) {
		lock_fpu_owner();
		if (is_fpu_owner()) {
			err = save_fp_context32(sc);
			unlock_fpu_owner();
		} else {
			unlock_fpu_owner();
			err = copy_fp_to_sigcontext32(sc);
		}
		if (likely(!err))
			break;
		/* touch the sigcontext and try again */
		err = __put_user(0, &sc->sc_fpregs[0]) |
			__put_user(0, &sc->sc_fpregs[31]) |
			__put_user(0, &sc->sc_fpc_csr);
		if (err)
			break;	/* really bad sigcontext */
	}
	return err;
}