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