Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) 					 &regs->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) 					 &regs->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), &regs->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, &regs->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(&regs->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) }