^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/arch/sh/kernel/signal.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/personality.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/binfmts.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/ucontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/fpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct fdpic_func_descriptor {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned long GOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * The following define adds a 64 byte gap between the signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * stack frame and previous contents of the stack. This allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * frame unwinding in a function epilogue but only if a frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * pointer is used in the function. This is necessary because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * current gcc compilers (<4.3) do not generate unwind info on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * SH for function epilogues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define UNWINDGUARD 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Do a signal return; undo the signal stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #if defined(CONFIG_CPU_SH2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define TRAP_NOARG 0xc320 /* Syscall w/no args (NR in R3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct sigframe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct sigcontext sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long extramask[_NSIG_WORDS-1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u16 retcode[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct rt_sigframe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct siginfo info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct ucontext uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u16 retcode[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #ifdef CONFIG_SH_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (!(boot_cpu_data.flags & CPU_HAS_FPU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) set_used_math();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return __copy_from_user(&tsk->thread.xstate->hardfpu, &sc->sc_fpregs[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) sizeof(long)*(16*2+2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (!(boot_cpu_data.flags & CPU_HAS_FPU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!used_math())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return __put_user(0, &sc->sc_ownedfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (__put_user(1, &sc->sc_ownedfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* This will cause a "finit" to be triggered by the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) attempted FPU operation by the 'current' process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) clear_used_math();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unlazy_fpu(tsk, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.xstate->hardfpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) sizeof(long)*(16*2+2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #endif /* CONFIG_SH_FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) COPY(regs[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) COPY(regs[2]); COPY(regs[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) COPY(regs[4]); COPY(regs[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) COPY(regs[6]); COPY(regs[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) COPY(regs[8]); COPY(regs[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) COPY(regs[10]); COPY(regs[11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) COPY(regs[12]); COPY(regs[13]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) COPY(regs[14]); COPY(regs[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) COPY(gbr); COPY(mach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) COPY(macl); COPY(pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) COPY(sr); COPY(pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #undef COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #ifdef CONFIG_SH_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (boot_cpu_data.flags & CPU_HAS_FPU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int owned_fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) regs->sr |= SR_FD; /* Release FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) clear_fpu(tsk, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) clear_used_math();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) err |= __get_user (owned_fp, &sc->sc_ownedfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (owned_fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) err |= restore_sigcontext_fpu(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) regs->tra = -1; /* disable syscall checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) err |= __get_user(*r0_p, &sc->sc_regs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) asmlinkage int sys_sigreturn(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct pt_regs *regs = current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Always make any pending restarted system calls return -EINTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) current->restart_block.fn = do_no_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (__get_user(set.sig[0], &frame->sc.oldmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) || (_NSIG_WORDS > 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) && __copy_from_user(&set.sig[1], &frame->extramask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) sizeof(frame->extramask))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (restore_sigcontext(regs, &frame->sc, &r0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) force_sig(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) asmlinkage int sys_rt_sigreturn(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct pt_regs *regs = current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* Always make any pending restarted system calls return -EINTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) current->restart_block.fn = do_no_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (restore_altstack(&frame->uc.uc_stack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) force_sig(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Set up a signal frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) COPY(regs[0]); COPY(regs[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) COPY(regs[2]); COPY(regs[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) COPY(regs[4]); COPY(regs[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) COPY(regs[6]); COPY(regs[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) COPY(regs[8]); COPY(regs[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) COPY(regs[10]); COPY(regs[11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) COPY(regs[12]); COPY(regs[13]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) COPY(regs[14]); COPY(regs[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) COPY(gbr); COPY(mach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) COPY(macl); COPY(pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) COPY(sr); COPY(pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #undef COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #ifdef CONFIG_SH_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) err |= save_sigcontext_fpu(sc, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* non-iBCS2 extensions.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) err |= __put_user(mask, &sc->oldmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Determine which stack to use..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static inline void __user *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ka->sa.sa_flags & SA_ONSTACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (sas_ss_flags(sp) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) sp = current->sas_ss_sp + current->sas_ss_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return (void __user *)((sp - (frame_size+UNWINDGUARD)) & -8ul);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* These symbols are defined with the addresses in the vsyscall page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) See vsyscall-trapa.S. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) extern void __kernel_sigreturn(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) extern void __kernel_rt_sigreturn(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int setup_frame(struct ksignal *ksig, sigset_t *set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int err = 0, sig = ksig->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (_NSIG_WORDS > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) err |= __copy_to_user(frame->extramask, &set->sig[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) sizeof(frame->extramask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Set up to return from userspace. If provided, use a stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) already in userspace. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ksig->ka.sa.sa_flags & SA_RESTORER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #ifdef CONFIG_VSYSCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) } else if (likely(current->mm->context.vdso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) regs->pr = VDSO_SYM(&__kernel_sigreturn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* Generate return code (system call to sigreturn) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) err |= __put_user(MOVW(7), &frame->retcode[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) err |= __put_user(OR_R0_R0, &frame->retcode[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) err |= __put_user(OR_R0_R0, &frame->retcode[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) err |= __put_user(OR_R0_R0, &frame->retcode[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) err |= __put_user(OR_R0_R0, &frame->retcode[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) err |= __put_user(OR_R0_R0, &frame->retcode[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) err |= __put_user((__NR_sigreturn), &frame->retcode[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) regs->pr = (unsigned long) frame->retcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Set up registers for signal handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) regs->regs[15] = (unsigned long) frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) regs->regs[4] = sig; /* Arg for signal handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) regs->regs[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) regs->regs[6] = (unsigned long) &frame->sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (current->personality & FDPIC_FUNCPTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct fdpic_func_descriptor __user *funcptr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) err |= __get_user(regs->pc, &funcptr->text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) err |= __get_user(regs->regs[12], &funcptr->GOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct rt_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int err = 0, sig = ksig->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) err |= copy_siginfo_to_user(&frame->info, &ksig->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* Create the ucontext. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) err |= __put_user(0, &frame->uc.uc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) err |= __put_user(NULL, &frame->uc.uc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) err |= __save_altstack(&frame->uc.uc_stack, regs->regs[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) err |= setup_sigcontext(&frame->uc.uc_mcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) regs, set->sig[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* Set up to return from userspace. If provided, use a stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) already in userspace. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ksig->ka.sa.sa_flags & SA_RESTORER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) #ifdef CONFIG_VSYSCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) } else if (likely(current->mm->context.vdso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) regs->pr = VDSO_SYM(&__kernel_rt_sigreturn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Generate return code (system call to rt_sigreturn) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) err |= __put_user(MOVW(7), &frame->retcode[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) err |= __put_user(OR_R0_R0, &frame->retcode[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) err |= __put_user(OR_R0_R0, &frame->retcode[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) err |= __put_user(OR_R0_R0, &frame->retcode[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) err |= __put_user(OR_R0_R0, &frame->retcode[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) err |= __put_user(OR_R0_R0, &frame->retcode[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) regs->pr = (unsigned long) frame->retcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* Set up registers for signal handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) regs->regs[15] = (unsigned long) frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) regs->regs[4] = sig; /* Arg for signal handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) regs->regs[5] = (unsigned long) &frame->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) regs->regs[6] = (unsigned long) &frame->uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (current->personality & FDPIC_FUNCPTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct fdpic_func_descriptor __user *funcptr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) err |= __get_user(regs->pc, &funcptr->text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) err |= __get_user(regs->regs[12], &funcptr->GOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct sigaction *sa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* If we're not from a syscall, bail out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (regs->tra < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* check for system call restart.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) switch (regs->regs[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case -ERESTART_RESTARTBLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case -ERESTARTNOHAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) no_system_call_restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) regs->regs[0] = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case -ERESTARTSYS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!(sa->sa_flags & SA_RESTART))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto no_system_call_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case -ERESTARTNOINTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) regs->regs[0] = save_r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * OK, we're invoking a handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) handle_signal(struct ksignal *ksig, struct pt_regs *regs, unsigned int save_r0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) sigset_t *oldset = sigmask_to_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* Set up the stack frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (ksig->ka.sa.sa_flags & SA_SIGINFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = setup_rt_frame(ksig, oldset, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = setup_frame(ksig, oldset, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * Note that 'init' is a special process: it doesn't get signals it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * want to handle. Thus you cannot kill init even with a SIGKILL even by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * mistake.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Note that we go through the signals twice: once to check the signals that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * the kernel can handle, and then we build all the user-level signal handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * stack-frames in one go after that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static void do_signal(struct pt_regs *regs, unsigned int save_r0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct ksignal ksig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * We want the common case to go fast, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * is why we may in certain cases get here from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * kernel mode. Just return without doing anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * if so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (get_signal(&ksig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) handle_syscall_restart(save_r0, regs, &ksig.ka.sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* Whee! Actually deliver the signal. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) handle_signal(&ksig, regs, save_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* Did we come from a system call? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (regs->tra >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Restart the system call - no handlers present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (regs->regs[0] == -ERESTARTNOHAND ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) regs->regs[0] == -ERESTARTSYS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) regs->regs[0] == -ERESTARTNOINTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) regs->regs[0] = save_r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) regs->regs[3] = __NR_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * If there's no signal to deliver, we just put the saved sigmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) restore_saved_sigmask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) unsigned long thread_info_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* deal with pending signal delivery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (thread_info_flags & _TIF_SIGPENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) do_signal(regs, save_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (thread_info_flags & _TIF_NOTIFY_RESUME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) tracehook_notify_resume(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }