^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Signal handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2008-2009 PetaLogix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2003,2004 John Williams <jwilliams@itee.uq.edu.au>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2001 NEC Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2001 Miles Bader <miles@gnu.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 1999,2000 Niibe Yutaka & Kaz Kojima
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 1991,1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This file was was derived from the sh version, arch/sh/kernel/signal.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * This file is subject to the terms and conditions of the GNU General
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Public License. See the file COPYING in the main directory of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * archive for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/personality.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/entry.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/ucontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Do a signal return; undo the signal stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct sigframe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct sigcontext sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned long extramask[_NSIG_WORDS-1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned long tramp[2]; /* signal trampoline */
^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) struct rt_sigframe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct siginfo info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct ucontext uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned long tramp[2]; /* signal trampoline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static int restore_sigcontext(struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct sigcontext __user *sc, int *rval_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define COPY(x) {err |= __get_user(regs->x, &sc->regs.x); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) COPY(r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) COPY(r1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) COPY(r2); COPY(r3); COPY(r4); COPY(r5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) COPY(r6); COPY(r7); COPY(r8); COPY(r9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) COPY(r10); COPY(r11); COPY(r12); COPY(r13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) COPY(r14); COPY(r15); COPY(r16); COPY(r17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) COPY(r18); COPY(r19); COPY(r20); COPY(r21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) COPY(r22); COPY(r23); COPY(r24); COPY(r25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) COPY(r26); COPY(r27); COPY(r28); COPY(r29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) COPY(r30); COPY(r31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) COPY(pc); COPY(ear); COPY(esr); COPY(fsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #undef COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *rval_p = regs->r3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct rt_sigframe __user *frame =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) (struct rt_sigframe __user *)(regs->r1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* Always make any pending restarted system calls return -EINTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) current->restart_block.fn = do_no_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (restore_altstack(&frame->uc.uc_stack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) force_sig(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * Set up a signal frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define COPY(x) {err |= __put_user(regs->x, &sc->regs.x); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) COPY(r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) COPY(r1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) COPY(r2); COPY(r3); COPY(r4); COPY(r5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) COPY(r6); COPY(r7); COPY(r8); COPY(r9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) COPY(r10); COPY(r11); COPY(r12); COPY(r13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) COPY(r14); COPY(r15); COPY(r16); COPY(r17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) COPY(r18); COPY(r19); COPY(r20); COPY(r21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) COPY(r22); COPY(r23); COPY(r24); COPY(r25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) COPY(r26); COPY(r27); COPY(r28); COPY(r29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) COPY(r30); COPY(r31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) COPY(pc); COPY(ear); COPY(esr); COPY(fsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #undef COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) err |= __put_user(mask, &sc->oldmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Determine which stack to use..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline void __user *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* Default to using normal stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned long sp = sigsp(regs->r1, ksig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return (void __user *)((sp - frame_size) & -8UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct rt_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int err = 0, sig = ksig->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned long address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) pmd_t *pmdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) pte_t *ptep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) frame = get_sigframe(ksig, regs, sizeof(*frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (ksig->ka.sa.sa_flags & SA_SIGINFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) err |= copy_siginfo_to_user(&frame->info, &ksig->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Create the ucontext. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) err |= __put_user(0, &frame->uc.uc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) err |= __put_user(NULL, &frame->uc.uc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) err |= __save_altstack(&frame->uc.uc_stack, regs->r1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) err |= setup_sigcontext(&frame->uc.uc_mcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) regs, set->sig[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* Set up to return from userspace. If provided, use a stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) already in userspace. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* minus 8 is offset to cater for "rtsd r15,8" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* addi r12, r0, __NR_sigreturn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) err |= __put_user(0x31800000 | __NR_rt_sigreturn ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) frame->tramp + 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* brki r14, 0x8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) err |= __put_user(0xb9cc0008, frame->tramp + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Return from sighandler will jump to the tramp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) Negative 8 offset because return is rtsd r15, 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) regs->r15 = ((unsigned long)frame->tramp)-8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) address = ((unsigned long)frame->tramp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pmdp = pmd_off(current->mm, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ptep = pte_offset_map(pmdp, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (pte_present(*ptep)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) address = (unsigned long) page_address(pte_page(*ptep));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* MS: I need add offset in page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* MS address is virtual */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) address = __virt_to_phys(address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) invalidate_icache_range(address, address + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) flush_dcache_range(address, address + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) pte_unmap(ptep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) flush_icache_range(address, address + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) flush_dcache_range(address, address + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* Set up registers for signal handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) regs->r1 = (unsigned long) frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* Signal handler args: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) regs->r5 = sig; /* arg 0: signum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* Offset to handle microblaze rtid r14, 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #ifdef DEBUG_SIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pr_info("SIG deliver (%s:%d): sp=%p pc=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) current->comm, current->pid, frame, regs->pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Handle restarting system calls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) switch (regs->r3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case -ERESTART_RESTARTBLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case -ERESTARTNOHAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!has_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) goto do_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) regs->r3 = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case -ERESTARTSYS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) regs->r3 = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case -ERESTARTNOINTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) do_restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* offset of 4 bytes to re-execute trap (brki) instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) regs->pc -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * OK, we're invoking a handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) handle_signal(struct ksignal *ksig, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) sigset_t *oldset = sigmask_to_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Set up the stack frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = setup_rt_frame(ksig, oldset, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * Note that 'init' is a special process: it doesn't get signals it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * want to handle. Thus you cannot kill init even with a SIGKILL even by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * mistake.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * Note that we go through the signals twice: once to check the signals that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * the kernel can handle, and then we build all the user-level signal handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * stack-frames in one go after that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static void do_signal(struct pt_regs *regs, int in_syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct ksignal ksig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #ifdef DEBUG_SIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pr_info("do signal: %p %d\n", regs, in_syscall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) regs->r12, current_thread_info()->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (get_signal(&ksig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* Whee! Actually deliver the signal. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (in_syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) handle_restart(regs, &ksig.ka, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) handle_signal(&ksig, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (in_syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) handle_restart(regs, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * If there's no signal to deliver, we just put the saved sigmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) restore_saved_sigmask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) asmlinkage void do_notify_resume(struct pt_regs *regs, int in_syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (test_thread_flag(TIF_SIGPENDING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) do_signal(regs, in_syscall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (test_thread_flag(TIF_NOTIFY_RESUME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) tracehook_notify_resume(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }