static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { unsigned int err = 0; #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]); COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]); COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]); COPY(gbr); COPY(mach); COPY(macl); COPY(pr); COPY(sr); COPY(pc); #undef COPY #if defined(__SH4__) { int owned_fp; struct task_struct *tsk = current; regs->sr |= SR_FD; /* Release FPU */ clear_fpu(tsk); current->used_math = 0; __get_user (owned_fp, &sc->sc_ownedfp); if (owned_fp) err |= restore_sigcontext_fpu(sc); } #endif return err; }
static int restore_sigframe(struct pt_regs *regs, struct rt_sigframe __user * sf) { sigset_t set; int err; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) { set_current_blocked(&set); } __get_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err); __get_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err); __get_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err); __get_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err); __get_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err); __get_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err); __get_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err); __get_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err); __get_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err); __get_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err); __get_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err); __get_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err); __get_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err); __get_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err); __get_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err); __get_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err); __get_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err); __get_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err); __get_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err); __get_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err); __get_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err); __get_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err); __get_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err); __get_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err); __get_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err); __get_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err); __get_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err); __get_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err); __get_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err); __get_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err); __get_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err); #if defined(CONFIG_HWZOL) __get_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err); __get_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err); __get_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err); #endif #if IS_ENABLED(CONFIG_FPU) err |= restore_sigcontext_fpu(regs, &sf->uc.uc_mcontext); #endif /* * Avoid sys_rt_sigreturn() restarting. */ forget_syscall(regs); return err; }
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, long long *r2_p) { unsigned int err = 0; unsigned long long current_sr, new_sr; #define SR_MASK 0xffff8cfd #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]); COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]); COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]); COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]); COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]); COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]); COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]); COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]); COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]); COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]); COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]); COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]); COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]); COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]); COPY(regs[60]); COPY(regs[61]); COPY(regs[62]); COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]); COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]); /* Prevent the signal handler manipulating SR in a way that can crash the kernel. i.e. only allow S, Q, M, PR, SZ, FR to be modified */ current_sr = regs->sr; err |= __get_user(new_sr, &sc->sc_sr); regs->sr &= SR_MASK; regs->sr |= (new_sr & ~SR_MASK); COPY(pc); #undef COPY /* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr * has been restored above.) */ err |= restore_sigcontext_fpu(regs, sc); regs->syscall_nr = -1; /* disable syscall checks */ err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]); return err; }
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p) { unsigned int err = 0; #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) COPY(regs[1]); COPY(regs[2]); COPY(regs[3]); COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]); COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]); COPY(gbr); COPY(mach); COPY(macl); COPY(pr); COPY(sr); COPY(pc); #undef COPY #ifdef CONFIG_SH_FPU if (boot_cpu_data.flags & CPU_HAS_FPU) { int owned_fp; struct task_struct *tsk = current; regs->sr |= SR_FD; /* Release FPU */ clear_fpu(tsk, regs); clear_used_math(); __get_user (owned_fp, &sc->sc_ownedfp); if (owned_fp) err |= restore_sigcontext_fpu(sc); } #endif regs->tra = -1; /* disable syscall checks */ err |= __get_user(*r0_p, &sc->sc_regs[0]); return err; }