^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * arch/xtensa/kernel/signal.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Default platform functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2005, 2006 Tensilica Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 1991, 1992 Linus Torvalds
^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) * Chris Zankel <chris@zankel.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Joe Taylor <joe@tensilica.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/errno.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/personality.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/ucontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/coprocessor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) extern struct task_struct *coproc_owners[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct rt_sigframe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct siginfo info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct ucontext uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) xtregs_opt_t opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) xtregs_user_t user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #if XTENSA_HAVE_COPROCESSORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) xtregs_coprocessor_t cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) } xtregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned char retcode[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int window[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Flush register windows stored in pt_regs to stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Returns 1 for errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) flush_window_regs_user(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) const unsigned long ws = regs->windowstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const unsigned long wb = regs->windowbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned long sp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned long wm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Return if no other frames. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (regs->wmask == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Rotate windowmask and skip empty frames. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) wm = (ws >> wb) | (ws << (XCHAL_NUM_AREGS / 4 - wb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) base = (XCHAL_NUM_AREGS / 4) - (regs->wmask >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* For call8 or call12 frames, we need the previous stack pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if ((regs->wmask & 2) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (__get_user(sp, (int*)(regs->areg[base * 4 + 1] - 12)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Spill frames to stack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) while (base < XCHAL_NUM_AREGS / 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int m = (wm >> base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int inc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Save registers a4..a7 (call8) or a4...a11 (call12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (m & 2) { /* call4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) inc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) } else if (m & 4) { /* call8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (copy_to_user(&SPILL_SLOT_CALL8(sp, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ®s->areg[(base + 1) * 4], 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) inc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) } else if (m & 8) { /* call12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (copy_to_user(&SPILL_SLOT_CALL12(sp, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ®s->areg[(base + 1) * 4], 32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) inc = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Save current frame a0..a3 under next SP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (copy_to_user(&SPILL_SLOT(sp, 0), ®s->areg[base * 4], 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Get current stack pointer for next loop iteration. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) sp = regs->areg[base * 4 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) base += inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) regs->wmask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) regs->windowstart = 1 << wb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) errout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Note: We don't copy double exception 'regs', we have to finish double exc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * first before we return to signal handler! This dbl.exc.handler might cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * another double exception, but I think we are fine as the situation is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * same as if we had returned to the signal handerl and got an interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * immediately...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) setup_sigcontext(struct rt_sigframe __user *frame, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct sigcontext __user *sc = &frame->uc.uc_mcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct thread_info *ti = current_thread_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) COPY(pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) COPY(ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) COPY(lbeg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) COPY(lend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) COPY(lcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) COPY(sar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #undef COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) err |= flush_window_regs_user(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) err |= __put_user(0, &sc->sc_xtregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #if XTENSA_HAVE_COPROCESSORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) coprocessor_flush_all(ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) coprocessor_release_all(ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) err |= __copy_to_user(&frame->xtregs.cp, &ti->xtregs_cp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) sizeof (frame->xtregs.cp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) err |= __copy_to_user(&frame->xtregs.opt, ®s->xtregs_opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) sizeof (xtregs_opt_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) err |= __copy_to_user(&frame->xtregs.user, &ti->xtregs_user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) sizeof (xtregs_user_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) err |= __put_user(err ? NULL : &frame->xtregs, &sc->sc_xtregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct sigcontext __user *sc = &frame->uc.uc_mcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct thread_info *ti = current_thread_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned long ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) COPY(pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) COPY(lbeg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) COPY(lend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) COPY(lcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) COPY(sar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #undef COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* All registers were flushed to stack. Start with a pristine frame. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) regs->wmask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) regs->windowbase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) regs->windowstart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) regs->syscall = NO_SYSCALL; /* disable syscall checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* For PS, restore only PS.CALLINC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * Assume that all other bits are either the same as for the signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * handler, or the user mode value doesn't matter (e.g. PS.OWB).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) err |= __get_user(ps, &sc->sc_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) regs->ps = (regs->ps & ~PS_CALLINC_MASK) | (ps & PS_CALLINC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Additional corruption checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if ((regs->lcount > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* The signal handler may have used coprocessors in which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * case they are still enabled. We disable them to force a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * reloading of the original task's CP state by the lazy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * context-switching mechanisms of CP exception handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * Also, we essentially discard any coprocessor state that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * signal handler created. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #if XTENSA_HAVE_COPROCESSORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) coprocessor_release_all(ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) err |= __copy_from_user(&ti->xtregs_cp, &frame->xtregs.cp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) sizeof (frame->xtregs.cp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) err |= __copy_from_user(&ti->xtregs_user, &frame->xtregs.user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sizeof (xtregs_user_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) err |= __copy_from_user(®s->xtregs_opt, &frame->xtregs.opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) sizeof (xtregs_opt_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return err;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Do a signal return; undo the signal stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) asmlinkage long xtensa_rt_sigreturn(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct pt_regs *regs = current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct rt_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* Always make any pending restarted system calls return -EINTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) current->restart_block.fn = do_no_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (regs->depc > 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) panic("rt_sigreturn in double exception!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) frame = (struct rt_sigframe __user *) regs->areg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (restore_sigcontext(regs, frame))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = regs->areg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (restore_altstack(&frame->uc.uc_stack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) force_sig(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return 0;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * Set up a signal frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) gen_return_code(unsigned char *codemem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * The 12-bit immediate is really split up within the 24-bit MOVI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * instruction. As long as the above system call numbers fit within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * 8-bits, the following code works fine. See the Xtensa ISA for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #if __NR_rt_sigreturn > 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) # error Generating the MOVI instruction below breaks!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) #ifdef __XTENSA_EB__ /* Big Endian version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Generate instruction: MOVI a2, __NR_rt_sigreturn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) err |= __put_user(0x22, &codemem[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) err |= __put_user(0x0a, &codemem[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) err |= __put_user(__NR_rt_sigreturn, &codemem[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* Generate instruction: SYSCALL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) err |= __put_user(0x00, &codemem[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) err |= __put_user(0x05, &codemem[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) err |= __put_user(0x00, &codemem[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) #elif defined __XTENSA_EL__ /* Little Endian version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Generate instruction: MOVI a2, __NR_rt_sigreturn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) err |= __put_user(0x22, &codemem[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) err |= __put_user(0xa0, &codemem[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) err |= __put_user(__NR_rt_sigreturn, &codemem[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* Generate instruction: SYSCALL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) err |= __put_user(0x00, &codemem[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) err |= __put_user(0x50, &codemem[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) err |= __put_user(0x00, &codemem[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) # error Must use compiler for Xtensa processors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* Flush generated code out of the data cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) __invalidate_icache_range((unsigned long)codemem, 6UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) __flush_invalidate_dcache_range((unsigned long)codemem, 6UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return err;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int setup_frame(struct ksignal *ksig, sigset_t *set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct rt_sigframe *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int err = 0, sig = ksig->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned long sp, ra, tp, ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) unsigned int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sp = regs->areg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if ((ksig->ka.sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sp = current->sas_ss_sp + current->sas_ss_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) frame = (void *)((sp - sizeof(*frame)) & -16ul);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (regs->depc > 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) panic ("Double exception sys_sigreturn\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (!access_ok(frame, sizeof(*frame))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) err |= copy_siginfo_to_user(&frame->info, &ksig->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* Create the user context. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) err |= __put_user(0, &frame->uc.uc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) err |= __put_user(0, &frame->uc.uc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) err |= __save_altstack(&frame->uc.uc_stack, regs->areg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) err |= setup_sigcontext(frame, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ksig->ka.sa.sa_flags & SA_RESTORER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ra = (unsigned long)ksig->ka.sa.sa_restorer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Create sys_rt_sigreturn syscall in stack frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) err |= gen_return_code(frame->retcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ra = (unsigned long) frame->retcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * Create signal handler execution context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * Return context not modified until this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* Set up registers for signal handler; preserve the threadptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) tp = regs->threadptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ps = regs->ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) (unsigned long) frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /* Set up a stack frame for a call4 if userspace uses windowed ABI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (ps & PS_WOE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) base = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) regs->areg[base] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) (((unsigned long) ra) & 0x3fffffff) | 0x40000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ps = (ps & ~(PS_CALLINC_MASK | PS_OWB_MASK)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) (1 << PS_CALLINC_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) regs->areg[base] = (unsigned long) ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) regs->areg[base + 2] = (unsigned long) sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) regs->areg[base + 3] = (unsigned long) &frame->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) regs->areg[base + 4] = (unsigned long) &frame->uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) regs->threadptr = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) regs->ps = ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pr_debug("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) current->comm, current->pid, sig, frame, regs->pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * Note that 'init' is a special process: it doesn't get signals it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * want to handle. Thus you cannot kill init even with a SIGKILL even by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * mistake.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * Note that we go through the signals twice: once to check the signals that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * the kernel can handle, and then we build all the user-level signal handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * stack-frames in one go after that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static void do_signal(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct ksignal ksig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) task_pt_regs(current)->icountlevel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (get_signal(&ksig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* Are we from a system call? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (regs->syscall != NO_SYSCALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* If so, check system call restarting.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) switch (regs->areg[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case -ERESTARTNOHAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) case -ERESTART_RESTARTBLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) regs->areg[2] = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case -ERESTARTSYS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) regs->areg[2] = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) case -ERESTARTNOINTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) regs->areg[2] = regs->syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) regs->pc -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (regs->areg[2] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* Whee! Actually deliver the signal. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* Set up the stack frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ret = setup_frame(&ksig, sigmask_to_save(), regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) signal_setup_done(ret, &ksig, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (current->ptrace & PT_SINGLESTEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) task_pt_regs(current)->icountlevel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* Did we come from a system call? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (regs->syscall != NO_SYSCALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* Restart the system call - no handlers present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) switch (regs->areg[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) case -ERESTARTNOHAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) case -ERESTARTSYS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case -ERESTARTNOINTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) regs->areg[2] = regs->syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) regs->pc -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case -ERESTART_RESTARTBLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) regs->areg[2] = __NR_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) regs->pc -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^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) /* If there's no signal to deliver, we just restore the saved mask. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) restore_saved_sigmask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (current->ptrace & PT_SINGLESTEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) task_pt_regs(current)->icountlevel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) void do_notify_resume(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (test_thread_flag(TIF_SIGPENDING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) do_signal(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (test_thread_flag(TIF_NOTIFY_RESUME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) tracehook_notify_resume(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }