^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2013-2014 Altera Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2011-2012 Tobias Klauser <tklauser@distanz.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2004 Microtronix Datacom Ltd
^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) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * License. See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * for more details.
^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/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/personality.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/ucontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Do a signal return; undo the signal stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Keep the return code on the stack quadword aligned!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * That makes the cache flush below easier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct rt_sigframe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct siginfo info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct ucontext uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static inline int rt_restore_ucontext(struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct switch_stack *sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct ucontext __user *uc, int *pr2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned long __user *gregs = uc->uc_mcontext.gregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Always make any pending restarted system calls return -EINTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) current->restart_block.fn = do_no_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) err = __get_user(temp, &uc->uc_mcontext.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (temp != MCONTEXT_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* restore passed registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) err |= __get_user(regs->r1, &gregs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) err |= __get_user(regs->r2, &gregs[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) err |= __get_user(regs->r3, &gregs[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) err |= __get_user(regs->r4, &gregs[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) err |= __get_user(regs->r5, &gregs[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) err |= __get_user(regs->r6, &gregs[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) err |= __get_user(regs->r7, &gregs[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) err |= __get_user(regs->r8, &gregs[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) err |= __get_user(regs->r9, &gregs[8]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) err |= __get_user(regs->r10, &gregs[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) err |= __get_user(regs->r11, &gregs[10]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) err |= __get_user(regs->r12, &gregs[11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) err |= __get_user(regs->r13, &gregs[12]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) err |= __get_user(regs->r14, &gregs[13]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) err |= __get_user(regs->r15, &gregs[14]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) err |= __get_user(sw->r16, &gregs[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) err |= __get_user(sw->r17, &gregs[16]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) err |= __get_user(sw->r18, &gregs[17]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) err |= __get_user(sw->r19, &gregs[18]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) err |= __get_user(sw->r20, &gregs[19]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) err |= __get_user(sw->r21, &gregs[20]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) err |= __get_user(sw->r22, &gregs[21]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) err |= __get_user(sw->r23, &gregs[22]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* gregs[23] is handled below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) err |= __get_user(sw->fp, &gregs[24]); /* Verify, should this be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) settable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) err |= __get_user(sw->gp, &gregs[25]); /* Verify, should this be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) settable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) err |= __get_user(temp, &gregs[26]); /* Not really necessary no user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) settable bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) err |= __get_user(regs->ea, &gregs[27]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) err |= __get_user(regs->ra, &gregs[23]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) err |= __get_user(regs->sp, &gregs[28]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) regs->orig_r2 = -1; /* disable syscall checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) err |= restore_altstack(&uc->uc_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *pr2 = regs->r2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) asmlinkage int do_rt_sigreturn(struct switch_stack *sw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct pt_regs *regs = (struct pt_regs *)(sw + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Verify, can we follow the stack back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct rt_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) frame = (struct rt_sigframe __user *) regs->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (rt_restore_ucontext(regs, sw, &frame->uc, &rval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) force_sig(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct switch_stack *sw = (struct switch_stack *)regs - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned long __user *gregs = uc->uc_mcontext.gregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) err |= __put_user(regs->r1, &gregs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) err |= __put_user(regs->r2, &gregs[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) err |= __put_user(regs->r3, &gregs[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) err |= __put_user(regs->r4, &gregs[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) err |= __put_user(regs->r5, &gregs[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) err |= __put_user(regs->r6, &gregs[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) err |= __put_user(regs->r7, &gregs[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) err |= __put_user(regs->r8, &gregs[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) err |= __put_user(regs->r9, &gregs[8]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) err |= __put_user(regs->r10, &gregs[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) err |= __put_user(regs->r11, &gregs[10]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) err |= __put_user(regs->r12, &gregs[11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) err |= __put_user(regs->r13, &gregs[12]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) err |= __put_user(regs->r14, &gregs[13]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) err |= __put_user(regs->r15, &gregs[14]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) err |= __put_user(sw->r16, &gregs[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) err |= __put_user(sw->r17, &gregs[16]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) err |= __put_user(sw->r18, &gregs[17]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) err |= __put_user(sw->r19, &gregs[18]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) err |= __put_user(sw->r20, &gregs[19]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) err |= __put_user(sw->r21, &gregs[20]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) err |= __put_user(sw->r22, &gregs[21]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) err |= __put_user(sw->r23, &gregs[22]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) err |= __put_user(regs->ra, &gregs[23]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) err |= __put_user(sw->fp, &gregs[24]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) err |= __put_user(sw->gp, &gregs[25]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) err |= __put_user(regs->ea, &gregs[27]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) err |= __put_user(regs->sp, &gregs[28]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline void __user *get_sigframe(struct ksignal *ksig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) size_t frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsigned long usp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Default to using normal stack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) usp = regs->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* This is the X/Open sanctioned signal stack switching. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) usp = sigsp(usp, ksig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Verify, is it 32 or 64 bit aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return (void __user *)((usp - frame_size) & -8UL);
^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) static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct rt_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) frame = get_sigframe(ksig, regs, sizeof(*frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (ksig->ka.sa.sa_flags & SA_SIGINFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) err |= copy_siginfo_to_user(&frame->info, &ksig->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Create the ucontext. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) err |= __put_user(0, &frame->uc.uc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) err |= __put_user(0, &frame->uc.uc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) err |= rt_setup_ucontext(&frame->uc, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) goto give_sigsegv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Set up to return from userspace; jump to fixed address sigreturn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) trampoline on kuser page. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) regs->ra = (unsigned long) (0x1044);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* Set up registers for signal handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) regs->sp = (unsigned long) frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) regs->r4 = (unsigned long) ksig->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) regs->r5 = (unsigned long) &frame->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) regs->r6 = (unsigned long) &frame->uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) regs->ea = (unsigned long) ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) give_sigsegv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) force_sigsegv(ksig->sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * OK, we're invoking a handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) sigset_t *oldset = sigmask_to_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* set up the stack frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = setup_rt_frame(ksig, oldset, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) signal_setup_done(ret, ksig, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int do_signal(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int restart = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct ksignal ksig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) current->thread.kregs = regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * If we were from a system call, check for system call restarting...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (regs->orig_r2 >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) continue_addr = regs->ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) restart_addr = continue_addr - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) retval = regs->r2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Prepare for system call restart. We do this here so that a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * debugger will see the already changed PC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) switch (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case ERESTART_RESTARTBLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) restart = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case ERESTARTNOHAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case ERESTARTSYS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case ERESTARTNOINTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) restart++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) regs->r2 = regs->orig_r2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) regs->r7 = regs->orig_r7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) regs->ea = restart_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (get_signal(&ksig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (unlikely(restart && regs->ea == restart_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (retval == ERESTARTNOHAND ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) retval == ERESTART_RESTARTBLOCK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) (retval == ERESTARTSYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) && !(ksig.ka.sa.sa_flags & SA_RESTART))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) regs->r2 = EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) regs->r7 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) regs->ea = continue_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) handle_signal(&ksig, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * No handler present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (unlikely(restart) && regs->ea == restart_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) regs->ea = continue_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) regs->r2 = __NR_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * If there's no signal to deliver, we just put the saved sigmask back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) restore_saved_sigmask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) asmlinkage int do_notify_resume(struct pt_regs *regs)
^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) * We want the common case to go fast, which is why we may in certain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * cases get here from kernel mode. Just return without doing anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * if so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (test_thread_flag(TIF_SIGPENDING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int restart = do_signal(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (unlikely(restart)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * Restart without handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * Deal with it without leaving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * the kernel space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) } else if (test_thread_flag(TIF_NOTIFY_RESUME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) tracehook_notify_resume(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }