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