static int protected_restore_fp_context32(struct sigcontext32 __user *sc, unsigned used_math) { int err, tmp __maybe_unused; bool restore_msa = cpu_has_msa && (used_math & USEDMATH_MSA); while (1) { lock_fpu_owner(); if (is_fpu_owner()) { err = restore_fp_context32(sc); if (restore_msa && !err) { enable_msa(); err = _restore_msa_context32(sc); } else { /* signal handler may have used MSA */ disable_msa(); } unlock_fpu_owner(); } else { unlock_fpu_owner(); err = copy_fp_from_sigcontext32(sc); if (restore_msa && !err) err = copy_msa_from_sigcontext32(sc); } if (likely(!err)) break; /* touch the sigcontext and try again */ err = __get_user(tmp, &sc->sc_fpregs[0]) | __get_user(tmp, &sc->sc_fpregs[31]) | __get_user(tmp, &sc->sc_fpc_csr); if (err) break; /* really bad sigcontext */ } return err; }
static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 __user *sc) { u32 used_math; int err = 0; s32 treg; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; err |= __get_user(regs->cp0_epc, &sc->sc_pc); err |= __get_user(regs->hi, &sc->sc_mdhi); err |= __get_user(regs->lo, &sc->sc_mdlo); if (cpu_has_dsp) { err |= __get_user(treg, &sc->sc_hi1); mthi1(treg); err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg); err |= __get_user(treg, &sc->sc_hi2); mthi2(treg); err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg); err |= __get_user(treg, &sc->sc_hi3); mthi3(treg); err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg); err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); } #define restore_gp_reg(i) do { \ err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ } while(0) restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9); restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12); restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15); restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18); restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21); restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24); restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27); restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30); restore_gp_reg(31); #undef restore_gp_reg err |= __get_user(used_math, &sc->sc_used_math); conditional_used_math(used_math); preempt_disable(); if (used_math()) { /* restore fpu context if we have used it before */ own_fpu(); err |= restore_fp_context32(sc); } else { /* signal handler may have used FPU. Give it up. */ lose_fpu(); } preempt_enable(); return err; }
static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) { int err = 0; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; err |= __get_user(regs->cp0_epc, &sc->sc_pc); err |= __get_user(regs->hi, &sc->sc_mdhi); err |= __get_user(regs->lo, &sc->sc_mdlo); #define restore_gp_reg(i) do { \ err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ } while(0) restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9); restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12); restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15); restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18); restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21); restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24); restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27); restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30); restore_gp_reg(31); #undef restore_gp_reg err |= __get_user(current->used_math, &sc->sc_used_math); preempt_disable(); if (current->used_math) { /* restore fpu context if we have used it before */ own_fpu(); err |= restore_fp_context32(sc); } else { /* signal handler may have used FPU. Give it up. */ lose_fpu(); } preempt_enable(); return err; }
static int protected_restore_fp_context32(struct sigcontext32 __user *sc) { int err, tmp __maybe_unused; while (1) { lock_fpu_owner(); own_fpu_inatomic(0); err = restore_fp_context32(sc); /* this might fail */ unlock_fpu_owner(); if (likely(!err)) break; /* touch the sigcontext and try again */ err = __get_user(tmp, &sc->sc_fpregs[0]) | __get_user(tmp, &sc->sc_fpregs[31]) | __get_user(tmp, &sc->sc_fpc_csr); if (err) break; /* really bad sigcontext */ } return err; }
static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) { int err = 0; BUG(); #if 0 err |= __get_user(regs->cp0_epc, &sc->sc_pc); err |= __get_user(regs->hi, &sc->sc_mdhi); err |= __get_user(regs->lo, &sc->sc_mdlo); #define restore_gp_reg(i) do { \ err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ } while(0) restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9); restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12); restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15); restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18); restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21); restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24); restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27); restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30); restore_gp_reg(31); #undef restore_gp_reg err |= __get_user(current->used_math, &sc->sc_used_math); if (current->used_math) { /* restore fpu context if we have used it before */ own_fpu(); err |= restore_fp_context32(sc); } else { /* signal handler may have used FPU. Give it up. */ lose_fpu(); } #endif return err; }
static int protected_restore_fp_context32(struct sigcontext32 __user *sc) { int err, tmp __maybe_unused; while (1) { lock_fpu_owner(); if (is_fpu_owner()) { err = restore_fp_context32(sc); unlock_fpu_owner(); } else { unlock_fpu_owner(); err = copy_fp_from_sigcontext32(sc); } if (likely(!err)) break; /* touch the sigcontext and try again */ err = __get_user(tmp, &sc->sc_fpregs[0]) | __get_user(tmp, &sc->sc_fpregs[31]) | __get_user(tmp, &sc->sc_fpc_csr); if (err) break; /* really bad sigcontext */ } return err; }