xref: /openbmc/linux/arch/arc/kernel/signal.c (revision 1b0b4c4238c0bdcf1a8ffa4c5431ec1d3fb9a345)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c3581039SVineet Gupta /*
3c3581039SVineet Gupta  * Signal Handling for ARC
4c3581039SVineet Gupta  *
5c3581039SVineet Gupta  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
6c3581039SVineet Gupta  *
7c3581039SVineet Gupta  * vineetg: Jan 2010 (Restarting of timer related syscalls)
8c3581039SVineet Gupta  *
9c3581039SVineet Gupta  * vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK)
10c3581039SVineet Gupta  *  -do_signal() supports TIF_RESTORE_SIGMASK
11c3581039SVineet Gupta  *  -do_signal() no loner needs oldset, required by OLD sys_sigsuspend
12c3581039SVineet Gupta  *  -sys_rt_sigsuspend() now comes from generic code, so discard arch implemen
13c3581039SVineet Gupta  *  -sys_sigsuspend() no longer needs to fudge ptregs, hence that arg removed
14c3581039SVineet Gupta  *  -sys_sigsuspend() no longer loops for do_signal(), sets TIF_xxx and leaves
15c3581039SVineet Gupta  *   the job to do_signal()
16c3581039SVineet Gupta  *
17c3581039SVineet Gupta  * vineetg: July 2009
18c3581039SVineet Gupta  *  -Modified Code to support the uClibc provided userland sigreturn stub
19c3581039SVineet Gupta  *   to avoid kernel synthesing it on user stack at runtime, costing TLB
20c3581039SVineet Gupta  *   probes and Cache line flushes.
21c3581039SVineet Gupta  *
22c3581039SVineet Gupta  * vineetg: July 2009
23c3581039SVineet Gupta  *  -In stash_usr_regs( ) and restore_usr_regs( ), save/restore of user regs
24c3581039SVineet Gupta  *   in done in block copy rather than one word at a time.
25c3581039SVineet Gupta  *   This saves around 2K of code and improves LMBench lat_sig <catch>
26c3581039SVineet Gupta  *
27c3581039SVineet Gupta  * rajeshwarr: Feb 2009
28c3581039SVineet Gupta  *  - Support for Realtime Signals
29c3581039SVineet Gupta  *
30c3581039SVineet Gupta  * vineetg: Aug 11th 2008: Bug #94183
31c3581039SVineet Gupta  *  -ViXS were still seeing crashes when using insmod to load drivers.
32c3581039SVineet Gupta  *   It turned out that the code to change Execute permssions for TLB entries
33c3581039SVineet Gupta  *   of user was not guarded for interrupts (mod_tlb_permission)
342547476aSAndrea Gelmini  *   This was causing TLB entries to be overwritten on unrelated indexes
35c3581039SVineet Gupta  *
36c3581039SVineet Gupta  * Vineetg: July 15th 2008: Bug #94183
37c3581039SVineet Gupta  *  -Exception happens in Delay slot of a JMP, and before user space resumes,
38c3581039SVineet Gupta  *   Signal is delivered (Ctrl + C) = >SIGINT.
39c3581039SVineet Gupta  *   setup_frame( ) sets up PC,SP,BLINK to enable user space signal handler
40c3581039SVineet Gupta  *   to run, but doesn't clear the Delay slot bit from status32. As a result,
41c3581039SVineet Gupta  *   on resuming user mode, signal handler branches off to BTA of orig JMP
42c3581039SVineet Gupta  *  -FIX: clear the DE bit from status32 in setup_frame( )
43c3581039SVineet Gupta  *
44c3581039SVineet Gupta  * Rahul Trivedi, Kanika Nema: Codito Technologies 2004
45c3581039SVineet Gupta  */
46c3581039SVineet Gupta 
47c3581039SVineet Gupta #include <linux/signal.h>
48c3581039SVineet Gupta #include <linux/ptrace.h>
49c3581039SVineet Gupta #include <linux/personality.h>
50c3581039SVineet Gupta #include <linux/uaccess.h>
51c3581039SVineet Gupta #include <linux/syscalls.h>
5203248addSEric W. Biederman #include <linux/resume_user_mode.h>
5368db0cf1SIngo Molnar #include <linux/sched/task_stack.h>
5468db0cf1SIngo Molnar 
55c3581039SVineet Gupta #include <asm/ucontext.h>
564d369680SVineet Gupta #include <asm/entry.h>
57c3581039SVineet Gupta 
58c3581039SVineet Gupta struct rt_sigframe {
59c3581039SVineet Gupta 	struct siginfo info;
60c3581039SVineet Gupta 	struct ucontext uc;
61c3581039SVineet Gupta #define MAGIC_SIGALTSTK		0x07302004
62c3581039SVineet Gupta 	unsigned int sigret_magic;
63c3581039SVineet Gupta };
64c3581039SVineet Gupta 
save_arcv2_regs(struct sigcontext __user * mctx,struct pt_regs * regs)65*358bca0bSVineet Gupta static int save_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs)
6696f1b001SVineet Gupta {
6796f1b001SVineet Gupta 	int err = 0;
6896f1b001SVineet Gupta #ifndef CONFIG_ISA_ARCOMPACT
6996f1b001SVineet Gupta 	struct user_regs_arcv2 v2abi;
7096f1b001SVineet Gupta 
7196f1b001SVineet Gupta 	v2abi.r30 = regs->r30;
7296f1b001SVineet Gupta #ifdef CONFIG_ARC_HAS_ACCL_REGS
7396f1b001SVineet Gupta 	v2abi.r58 = regs->r58;
7496f1b001SVineet Gupta 	v2abi.r59 = regs->r59;
7596f1b001SVineet Gupta #else
7696f1b001SVineet Gupta 	v2abi.r58 = v2abi.r59 = 0;
7796f1b001SVineet Gupta #endif
78*358bca0bSVineet Gupta 	err = __copy_to_user(&mctx->v2abi, (void const *)&v2abi, sizeof(v2abi));
7996f1b001SVineet Gupta #endif
8096f1b001SVineet Gupta 	return err;
8196f1b001SVineet Gupta }
8296f1b001SVineet Gupta 
restore_arcv2_regs(struct sigcontext __user * mctx,struct pt_regs * regs)83*358bca0bSVineet Gupta static int restore_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs)
8496f1b001SVineet Gupta {
8596f1b001SVineet Gupta 	int err = 0;
8696f1b001SVineet Gupta #ifndef CONFIG_ISA_ARCOMPACT
8796f1b001SVineet Gupta 	struct user_regs_arcv2 v2abi;
8896f1b001SVineet Gupta 
8996f1b001SVineet Gupta 	err = __copy_from_user(&v2abi, &mctx->v2abi, sizeof(v2abi));
9096f1b001SVineet Gupta 
9196f1b001SVineet Gupta 	regs->r30 = v2abi.r30;
9296f1b001SVineet Gupta #ifdef CONFIG_ARC_HAS_ACCL_REGS
9396f1b001SVineet Gupta 	regs->r58 = v2abi.r58;
9496f1b001SVineet Gupta 	regs->r59 = v2abi.r59;
9596f1b001SVineet Gupta #endif
9696f1b001SVineet Gupta #endif
9796f1b001SVineet Gupta 	return err;
9896f1b001SVineet Gupta }
9996f1b001SVineet Gupta 
100c3581039SVineet Gupta static int
stash_usr_regs(struct rt_sigframe __user * sf,struct pt_regs * regs,sigset_t * set)101c3581039SVineet Gupta stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
102c3581039SVineet Gupta 	       sigset_t *set)
103c3581039SVineet Gupta {
104c3581039SVineet Gupta 	int err;
1056ffb9c8cSVineet Gupta 	struct user_regs_struct uregs;
1066ffb9c8cSVineet Gupta 
1076ffb9c8cSVineet Gupta 	uregs.scratch.bta	= regs->bta;
1086ffb9c8cSVineet Gupta 	uregs.scratch.lp_start	= regs->lp_start;
1096ffb9c8cSVineet Gupta 	uregs.scratch.lp_end	= regs->lp_end;
1106ffb9c8cSVineet Gupta 	uregs.scratch.lp_count	= regs->lp_count;
1116ffb9c8cSVineet Gupta 	uregs.scratch.status32	= regs->status32;
1126ffb9c8cSVineet Gupta 	uregs.scratch.ret	= regs->ret;
1136ffb9c8cSVineet Gupta 	uregs.scratch.blink	= regs->blink;
1146ffb9c8cSVineet Gupta 	uregs.scratch.fp	= regs->fp;
1156ffb9c8cSVineet Gupta 	uregs.scratch.gp	= regs->r26;
1166ffb9c8cSVineet Gupta 	uregs.scratch.r12	= regs->r12;
1176ffb9c8cSVineet Gupta 	uregs.scratch.r11	= regs->r11;
1186ffb9c8cSVineet Gupta 	uregs.scratch.r10	= regs->r10;
1196ffb9c8cSVineet Gupta 	uregs.scratch.r9	= regs->r9;
1206ffb9c8cSVineet Gupta 	uregs.scratch.r8	= regs->r8;
1216ffb9c8cSVineet Gupta 	uregs.scratch.r7	= regs->r7;
1226ffb9c8cSVineet Gupta 	uregs.scratch.r6	= regs->r6;
1236ffb9c8cSVineet Gupta 	uregs.scratch.r5	= regs->r5;
1246ffb9c8cSVineet Gupta 	uregs.scratch.r4	= regs->r4;
1256ffb9c8cSVineet Gupta 	uregs.scratch.r3	= regs->r3;
1266ffb9c8cSVineet Gupta 	uregs.scratch.r2	= regs->r2;
1276ffb9c8cSVineet Gupta 	uregs.scratch.r1	= regs->r1;
1286ffb9c8cSVineet Gupta 	uregs.scratch.r0	= regs->r0;
1296ffb9c8cSVineet Gupta 	uregs.scratch.sp	= regs->sp;
1306ffb9c8cSVineet Gupta 
1316ffb9c8cSVineet Gupta 	err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch,
132c3581039SVineet Gupta 			     sizeof(sf->uc.uc_mcontext.regs.scratch));
13396f1b001SVineet Gupta 
13496f1b001SVineet Gupta 	if (is_isa_arcv2())
13596f1b001SVineet Gupta 		err |= save_arcv2_regs(&(sf->uc.uc_mcontext), regs);
13696f1b001SVineet Gupta 
137c3581039SVineet Gupta 	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
138c3581039SVineet Gupta 
13946e15218SWang Qing 	return err ? -EFAULT : 0;
140c3581039SVineet Gupta }
141c3581039SVineet Gupta 
restore_usr_regs(struct pt_regs * regs,struct rt_sigframe __user * sf)142c3581039SVineet Gupta static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
143c3581039SVineet Gupta {
144c3581039SVineet Gupta 	sigset_t set;
145c3581039SVineet Gupta 	int err;
1466ffb9c8cSVineet Gupta 	struct user_regs_struct uregs;
147c3581039SVineet Gupta 
148c3581039SVineet Gupta 	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
1496ffb9c8cSVineet Gupta 	err |= __copy_from_user(&uregs.scratch,
1506ffb9c8cSVineet Gupta 				&(sf->uc.uc_mcontext.regs.scratch),
151c3581039SVineet Gupta 				sizeof(sf->uc.uc_mcontext.regs.scratch));
15296f1b001SVineet Gupta 
15396f1b001SVineet Gupta 	if (is_isa_arcv2())
15496f1b001SVineet Gupta 		err |= restore_arcv2_regs(&(sf->uc.uc_mcontext), regs);
15596f1b001SVineet Gupta 
1567798bf21SAl Viro 	if (err)
15746e15218SWang Qing 		return -EFAULT;
158c3581039SVineet Gupta 
1597798bf21SAl Viro 	set_current_blocked(&set);
1606ffb9c8cSVineet Gupta 	regs->bta	= uregs.scratch.bta;
1616ffb9c8cSVineet Gupta 	regs->lp_start	= uregs.scratch.lp_start;
1626ffb9c8cSVineet Gupta 	regs->lp_end	= uregs.scratch.lp_end;
1636ffb9c8cSVineet Gupta 	regs->lp_count	= uregs.scratch.lp_count;
1646ffb9c8cSVineet Gupta 	regs->status32	= uregs.scratch.status32;
1656ffb9c8cSVineet Gupta 	regs->ret	= uregs.scratch.ret;
1666ffb9c8cSVineet Gupta 	regs->blink	= uregs.scratch.blink;
1676ffb9c8cSVineet Gupta 	regs->fp	= uregs.scratch.fp;
1686ffb9c8cSVineet Gupta 	regs->r26	= uregs.scratch.gp;
1696ffb9c8cSVineet Gupta 	regs->r12	= uregs.scratch.r12;
1706ffb9c8cSVineet Gupta 	regs->r11	= uregs.scratch.r11;
1716ffb9c8cSVineet Gupta 	regs->r10	= uregs.scratch.r10;
1726ffb9c8cSVineet Gupta 	regs->r9	= uregs.scratch.r9;
1736ffb9c8cSVineet Gupta 	regs->r8	= uregs.scratch.r8;
1746ffb9c8cSVineet Gupta 	regs->r7	= uregs.scratch.r7;
1756ffb9c8cSVineet Gupta 	regs->r6	= uregs.scratch.r6;
1766ffb9c8cSVineet Gupta 	regs->r5	= uregs.scratch.r5;
1776ffb9c8cSVineet Gupta 	regs->r4	= uregs.scratch.r4;
1786ffb9c8cSVineet Gupta 	regs->r3	= uregs.scratch.r3;
1796ffb9c8cSVineet Gupta 	regs->r2	= uregs.scratch.r2;
1806ffb9c8cSVineet Gupta 	regs->r1	= uregs.scratch.r1;
1816ffb9c8cSVineet Gupta 	regs->r0	= uregs.scratch.r0;
1826ffb9c8cSVineet Gupta 	regs->sp	= uregs.scratch.sp;
1836ffb9c8cSVineet Gupta 
1847798bf21SAl Viro 	return 0;
185c3581039SVineet Gupta }
186c3581039SVineet Gupta 
is_do_ss_needed(unsigned int magic)187c3581039SVineet Gupta static inline int is_do_ss_needed(unsigned int magic)
188c3581039SVineet Gupta {
189c3581039SVineet Gupta 	if (MAGIC_SIGALTSTK == magic)
190c3581039SVineet Gupta 		return 1;
191c3581039SVineet Gupta 	else
192c3581039SVineet Gupta 		return 0;
193c3581039SVineet Gupta }
194c3581039SVineet Gupta 
SYSCALL_DEFINE0(rt_sigreturn)195c3581039SVineet Gupta SYSCALL_DEFINE0(rt_sigreturn)
196c3581039SVineet Gupta {
197c3581039SVineet Gupta 	struct rt_sigframe __user *sf;
198c3581039SVineet Gupta 	unsigned int magic;
199c3581039SVineet Gupta 	struct pt_regs *regs = current_pt_regs();
200c3581039SVineet Gupta 
201c3581039SVineet Gupta 	/* Always make any pending restarted system calls return -EINTR */
202f56141e3SAndy Lutomirski 	current->restart_block.fn = do_no_restart_syscall;
203c3581039SVineet Gupta 
204c3581039SVineet Gupta 	/* Since we stacked the signal on a word boundary,
205c3581039SVineet Gupta 	 * then 'sp' should be word aligned here.  If it's
206c3581039SVineet Gupta 	 * not, then the user is trying to mess with us.
207c3581039SVineet Gupta 	 */
208c3581039SVineet Gupta 	if (regs->sp & 3)
209c3581039SVineet Gupta 		goto badframe;
210c3581039SVineet Gupta 
211c3581039SVineet Gupta 	sf = (struct rt_sigframe __force __user *)(regs->sp);
212c3581039SVineet Gupta 
21396d4f267SLinus Torvalds 	if (!access_ok(sf, sizeof(*sf)))
214c3581039SVineet Gupta 		goto badframe;
215c3581039SVineet Gupta 
21610469350SChristian Ruppert 	if (__get_user(magic, &sf->sigret_magic))
217c3581039SVineet Gupta 		goto badframe;
218c3581039SVineet Gupta 
219c3581039SVineet Gupta 	if (unlikely(is_do_ss_needed(magic)))
220c3581039SVineet Gupta 		if (restore_altstack(&sf->uc.uc_stack))
221c3581039SVineet Gupta 			goto badframe;
222c3581039SVineet Gupta 
22310469350SChristian Ruppert 	if (restore_usr_regs(regs, sf))
22410469350SChristian Ruppert 		goto badframe;
22510469350SChristian Ruppert 
22655bb9480SVineet Gupta 	/* Don't restart from sigreturn */
22755bb9480SVineet Gupta 	syscall_wont_restart(regs);
22855bb9480SVineet Gupta 
229e4140819SVineet Gupta 	/*
230e4140819SVineet Gupta 	 * Ensure that sigreturn always returns to user mode (in case the
231e4140819SVineet Gupta 	 * regs saved on user stack got fudged between save and sigreturn)
232e4140819SVineet Gupta 	 * Otherwise it is easy to panic the kernel with a custom
233e4140819SVineet Gupta 	 * signal handler and/or restorer which clobberes the status32/ret
234e4140819SVineet Gupta 	 * to return to a bogus location in kernel mode.
235e4140819SVineet Gupta 	 */
236e4140819SVineet Gupta 	regs->status32 |= STATUS_U_MASK;
237e4140819SVineet Gupta 
238c3581039SVineet Gupta 	return regs->r0;
239c3581039SVineet Gupta 
240c3581039SVineet Gupta badframe:
2413cf5d076SEric W. Biederman 	force_sig(SIGSEGV);
242c3581039SVineet Gupta 	return 0;
243c3581039SVineet Gupta }
244c3581039SVineet Gupta 
245c3581039SVineet Gupta /*
246c3581039SVineet Gupta  * Determine which stack to use..
247c3581039SVineet Gupta  */
get_sigframe(struct ksignal * ksig,struct pt_regs * regs,unsigned long framesize)2485290dd79SRichard Weinberger static inline void __user *get_sigframe(struct ksignal *ksig,
249c3581039SVineet Gupta 					struct pt_regs *regs,
250c3581039SVineet Gupta 					unsigned long framesize)
251c3581039SVineet Gupta {
2525290dd79SRichard Weinberger 	unsigned long sp = sigsp(regs->sp, ksig);
253c3581039SVineet Gupta 	void __user *frame;
254c3581039SVineet Gupta 
255c3581039SVineet Gupta 	/* No matter what happens, 'sp' must be word
256c3581039SVineet Gupta 	 * aligned otherwise nasty things could happen
257c3581039SVineet Gupta 	 */
258c3581039SVineet Gupta 
259c3581039SVineet Gupta 	/* ATPCS B01 mandates 8-byte alignment */
260c3581039SVineet Gupta 	frame = (void __user *)((sp - framesize) & ~7);
261c3581039SVineet Gupta 
262c3581039SVineet Gupta 	/* Check that we can actually write to the signal frame */
26396d4f267SLinus Torvalds 	if (!access_ok(frame, framesize))
264c3581039SVineet Gupta 		frame = NULL;
265c3581039SVineet Gupta 
266c3581039SVineet Gupta 	return frame;
267c3581039SVineet Gupta }
268c3581039SVineet Gupta 
269c3581039SVineet Gupta static int
setup_rt_frame(struct ksignal * ksig,sigset_t * set,struct pt_regs * regs)270f6dd2a3fSRichard Weinberger setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
271c3581039SVineet Gupta {
272c3581039SVineet Gupta 	struct rt_sigframe __user *sf;
273c3581039SVineet Gupta 	unsigned int magic = 0;
274c3581039SVineet Gupta 	int err = 0;
275c3581039SVineet Gupta 
2765290dd79SRichard Weinberger 	sf = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));
277c3581039SVineet Gupta 	if (!sf)
278c3581039SVineet Gupta 		return 1;
279c3581039SVineet Gupta 
280c3581039SVineet Gupta 	/*
28110469350SChristian Ruppert 	 * w/o SA_SIGINFO, struct ucontext is partially populated (only
28210469350SChristian Ruppert 	 * uc_mcontext/uc_sigmask) for kernel's normal user state preservation
28310469350SChristian Ruppert 	 * during signal handler execution. This works for SA_SIGINFO as well
28410469350SChristian Ruppert 	 * although the semantics are now overloaded (the same reg state can be
28510469350SChristian Ruppert 	 * inspected by userland: but are they allowed to fiddle with it ?
28610469350SChristian Ruppert 	 */
28710469350SChristian Ruppert 	err |= stash_usr_regs(sf, regs, set);
28810469350SChristian Ruppert 
28910469350SChristian Ruppert 	/*
290c3581039SVineet Gupta 	 * SA_SIGINFO requires 3 args to signal handler:
291c3581039SVineet Gupta 	 *  #1: sig-no (common to any handler)
292c3581039SVineet Gupta 	 *  #2: struct siginfo
293c3581039SVineet Gupta 	 *  #3: struct ucontext (completely populated)
294c3581039SVineet Gupta 	 */
295f6dd2a3fSRichard Weinberger 	if (unlikely(ksig->ka.sa.sa_flags & SA_SIGINFO)) {
296f6dd2a3fSRichard Weinberger 		err |= copy_siginfo_to_user(&sf->info, &ksig->info);
297c3581039SVineet Gupta 		err |= __put_user(0, &sf->uc.uc_flags);
298c3581039SVineet Gupta 		err |= __put_user(NULL, &sf->uc.uc_link);
299c3581039SVineet Gupta 		err |= __save_altstack(&sf->uc.uc_stack, regs->sp);
300c3581039SVineet Gupta 
301c3581039SVineet Gupta 		/* setup args 2 and 3 for user mode handler */
302c3581039SVineet Gupta 		regs->r1 = (unsigned long)&sf->info;
303c3581039SVineet Gupta 		regs->r2 = (unsigned long)&sf->uc;
304c3581039SVineet Gupta 
305c3581039SVineet Gupta 		/*
306f79f7a2dSBhaskar Chowdhury 		 * small optim to avoid unconditionally calling do_sigaltstack
307c3581039SVineet Gupta 		 * in sigreturn path, now that we only have rt_sigreturn
308c3581039SVineet Gupta 		 */
309c3581039SVineet Gupta 		magic = MAGIC_SIGALTSTK;
310c3581039SVineet Gupta 	}
311c3581039SVineet Gupta 
312c3581039SVineet Gupta 	err |= __put_user(magic, &sf->sigret_magic);
313c3581039SVineet Gupta 	if (err)
314c3581039SVineet Gupta 		return err;
315c3581039SVineet Gupta 
316c3581039SVineet Gupta 	/* #1 arg to the user Signal handler */
317e6de3ca9SRichard Weinberger 	regs->r0 = ksig->sig;
318c3581039SVineet Gupta 
319c3581039SVineet Gupta 	/* setup PC of user space signal handler */
320f6dd2a3fSRichard Weinberger 	regs->ret = (unsigned long)ksig->ka.sa.sa_handler;
321c3581039SVineet Gupta 
322c3581039SVineet Gupta 	/*
323ecaa054fSJulia Lawall 	 * handler returns using sigreturn stub provided already by userspace
324e4140819SVineet Gupta 	 * If not, nuke the process right away
325c3581039SVineet Gupta 	 */
326e4140819SVineet Gupta 	if(!(ksig->ka.sa.sa_flags & SA_RESTORER))
327e4140819SVineet Gupta 		return 1;
328e4140819SVineet Gupta 
329f6dd2a3fSRichard Weinberger 	regs->blink = (unsigned long)ksig->ka.sa.sa_restorer;
330c3581039SVineet Gupta 
331c3581039SVineet Gupta 	/* User Stack for signal handler will be above the frame just carved */
332c3581039SVineet Gupta 	regs->sp = (unsigned long)sf;
333c3581039SVineet Gupta 
334c3581039SVineet Gupta 	/*
335c3581039SVineet Gupta 	 * Bug 94183, Clear the DE bit, so that when signal handler
336c3581039SVineet Gupta 	 * starts to run, it doesn't use BTA
337c3581039SVineet Gupta 	 */
338c3581039SVineet Gupta 	regs->status32 &= ~STATUS_DE_MASK;
339c3581039SVineet Gupta 	regs->status32 |= STATUS_L_MASK;
340c3581039SVineet Gupta 
341c3581039SVineet Gupta 	return err;
342c3581039SVineet Gupta }
343c3581039SVineet Gupta 
arc_restart_syscall(struct k_sigaction * ka,struct pt_regs * regs)344c3581039SVineet Gupta static void arc_restart_syscall(struct k_sigaction *ka, struct pt_regs *regs)
345c3581039SVineet Gupta {
346c3581039SVineet Gupta 	switch (regs->r0) {
347c3581039SVineet Gupta 	case -ERESTART_RESTARTBLOCK:
348c3581039SVineet Gupta 	case -ERESTARTNOHAND:
349c3581039SVineet Gupta 		/*
350c3581039SVineet Gupta 		 * ERESTARTNOHAND means that the syscall should
351c3581039SVineet Gupta 		 * only be restarted if there was no handler for
352c3581039SVineet Gupta 		 * the signal, and since we only get here if there
353c3581039SVineet Gupta 		 * is a handler, we don't restart
354c3581039SVineet Gupta 		 */
355c3581039SVineet Gupta 		regs->r0 = -EINTR;   /* ERESTART_xxx is internal */
356c3581039SVineet Gupta 		break;
357c3581039SVineet Gupta 
358c3581039SVineet Gupta 	case -ERESTARTSYS:
359c3581039SVineet Gupta 		/*
360c3581039SVineet Gupta 		 * ERESTARTSYS means to restart the syscall if
361c3581039SVineet Gupta 		 * there is no handler or the handler was
362c3581039SVineet Gupta 		 * registered with SA_RESTART
363c3581039SVineet Gupta 		 */
364c3581039SVineet Gupta 		if (!(ka->sa.sa_flags & SA_RESTART)) {
365c3581039SVineet Gupta 			regs->r0 = -EINTR;
366c3581039SVineet Gupta 			break;
367c3581039SVineet Gupta 		}
368df561f66SGustavo A. R. Silva 		fallthrough;
369c3581039SVineet Gupta 
370c3581039SVineet Gupta 	case -ERESTARTNOINTR:
371c3581039SVineet Gupta 		/*
372c3581039SVineet Gupta 		 * ERESTARTNOINTR means that the syscall should
373c3581039SVineet Gupta 		 * be called again after the signal handler returns.
374c3581039SVineet Gupta 		 * Setup reg state just as it was before doing the trap
375c3581039SVineet Gupta 		 * r0 has been clobbered with sys call ret code thus it
376c3581039SVineet Gupta 		 * needs to be reloaded with orig first arg to syscall
377c3581039SVineet Gupta 		 * in orig_r0. Rest of relevant reg-file:
378c3581039SVineet Gupta 		 * r8 (syscall num) and (r1 - r7) will be reset to
379c3581039SVineet Gupta 		 * their orig user space value when we ret from kernel
380c3581039SVineet Gupta 		 */
381c3581039SVineet Gupta 		regs->r0 = regs->orig_r0;
3821f6ccfffSVineet Gupta 		regs->ret -= is_isa_arcv2() ? 2 : 4;
383c3581039SVineet Gupta 		break;
384c3581039SVineet Gupta 	}
385c3581039SVineet Gupta }
386c3581039SVineet Gupta 
387c3581039SVineet Gupta /*
388c3581039SVineet Gupta  * OK, we're invoking a handler
389c3581039SVineet Gupta  */
390c3581039SVineet Gupta static void
handle_signal(struct ksignal * ksig,struct pt_regs * regs)391f6dd2a3fSRichard Weinberger handle_signal(struct ksignal *ksig, struct pt_regs *regs)
392c3581039SVineet Gupta {
393c3581039SVineet Gupta 	sigset_t *oldset = sigmask_to_save();
394e4140819SVineet Gupta 	int failed;
395c3581039SVineet Gupta 
396c3581039SVineet Gupta 	/* Set up the stack frame */
397e4140819SVineet Gupta 	failed = setup_rt_frame(ksig, oldset, regs);
398c3581039SVineet Gupta 
399e4140819SVineet Gupta 	signal_setup_done(failed, ksig, 0);
400c3581039SVineet Gupta }
401c3581039SVineet Gupta 
do_signal(struct pt_regs * regs)402c3581039SVineet Gupta void do_signal(struct pt_regs *regs)
403c3581039SVineet Gupta {
404f6dd2a3fSRichard Weinberger 	struct ksignal ksig;
405c3581039SVineet Gupta 	int restart_scall;
406c3581039SVineet Gupta 
40755bb9480SVineet Gupta 	restart_scall = in_syscall(regs) && syscall_restartable(regs);
408c3581039SVineet Gupta 
40953855e12SJens Axboe 	if (test_thread_flag(TIF_SIGPENDING) && get_signal(&ksig)) {
41055bb9480SVineet Gupta 		if (restart_scall) {
411f6dd2a3fSRichard Weinberger 			arc_restart_syscall(&ksig.ka, regs);
41255bb9480SVineet Gupta 			syscall_wont_restart(regs);	/* No more restarts */
41355bb9480SVineet Gupta 		}
414f6dd2a3fSRichard Weinberger 		handle_signal(&ksig, regs);
415c3581039SVineet Gupta 		return;
416c3581039SVineet Gupta 	}
417c3581039SVineet Gupta 
418c3581039SVineet Gupta 	if (restart_scall) {
419c3581039SVineet Gupta 		/* No handler for syscall: restart it */
420c3581039SVineet Gupta 		if (regs->r0 == -ERESTARTNOHAND ||
421c3581039SVineet Gupta 		    regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) {
422c3581039SVineet Gupta 			regs->r0 = regs->orig_r0;
4231f6ccfffSVineet Gupta 			regs->ret -= is_isa_arcv2() ? 2 : 4;
424c3581039SVineet Gupta 		} else if (regs->r0 == -ERESTART_RESTARTBLOCK) {
425c3581039SVineet Gupta 			regs->r8 = __NR_restart_syscall;
4261f6ccfffSVineet Gupta 			regs->ret -= is_isa_arcv2() ? 2 : 4;
427c3581039SVineet Gupta 		}
42855bb9480SVineet Gupta 		syscall_wont_restart(regs);	/* No more restarts */
429c3581039SVineet Gupta 	}
430c3581039SVineet Gupta 
431c3581039SVineet Gupta 	/* If there's no signal to deliver, restore the saved sigmask back */
432c3581039SVineet Gupta 	restore_saved_sigmask();
433c3581039SVineet Gupta }
434c3581039SVineet Gupta 
do_notify_resume(struct pt_regs * regs)435c3581039SVineet Gupta void do_notify_resume(struct pt_regs *regs)
436c3581039SVineet Gupta {
437c3581039SVineet Gupta 	/*
438f79f7a2dSBhaskar Chowdhury 	 * ASM glue guarantees that this is only called when returning to
439c3581039SVineet Gupta 	 * user mode
440c3581039SVineet Gupta 	 */
4413c532798SJens Axboe 	if (test_thread_flag(TIF_NOTIFY_RESUME))
44203248addSEric W. Biederman 		resume_user_mode_work(regs);
443c3581039SVineet Gupta }
444