xref: /openbmc/linux/arch/arm64/kernel/signal.c (revision 9842ceae)
12c020ed8SCatalin Marinas /*
22c020ed8SCatalin Marinas  * Based on arch/arm/kernel/signal.c
32c020ed8SCatalin Marinas  *
42c020ed8SCatalin Marinas  * Copyright (C) 1995-2009 Russell King
52c020ed8SCatalin Marinas  * Copyright (C) 2012 ARM Ltd.
62c020ed8SCatalin Marinas  *
72c020ed8SCatalin Marinas  * This program is free software; you can redistribute it and/or modify
82c020ed8SCatalin Marinas  * it under the terms of the GNU General Public License version 2 as
92c020ed8SCatalin Marinas  * published by the Free Software Foundation.
102c020ed8SCatalin Marinas  *
112c020ed8SCatalin Marinas  * This program is distributed in the hope that it will be useful,
122c020ed8SCatalin Marinas  * but WITHOUT ANY WARRANTY; without even the implied warranty of
132c020ed8SCatalin Marinas  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
142c020ed8SCatalin Marinas  * GNU General Public License for more details.
152c020ed8SCatalin Marinas  *
162c020ed8SCatalin Marinas  * You should have received a copy of the GNU General Public License
172c020ed8SCatalin Marinas  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
182c020ed8SCatalin Marinas  */
192c020ed8SCatalin Marinas 
20fd92d4a5SAKASHI Takahiro #include <linux/compat.h>
212c020ed8SCatalin Marinas #include <linux/errno.h>
222c020ed8SCatalin Marinas #include <linux/signal.h>
232c020ed8SCatalin Marinas #include <linux/personality.h>
242c020ed8SCatalin Marinas #include <linux/freezer.h>
252c020ed8SCatalin Marinas #include <linux/uaccess.h>
262c020ed8SCatalin Marinas #include <linux/tracehook.h>
272c020ed8SCatalin Marinas #include <linux/ratelimit.h>
282c020ed8SCatalin Marinas 
292c020ed8SCatalin Marinas #include <asm/debug-monitors.h>
302c020ed8SCatalin Marinas #include <asm/elf.h>
312c020ed8SCatalin Marinas #include <asm/cacheflush.h>
322c020ed8SCatalin Marinas #include <asm/ucontext.h>
332c020ed8SCatalin Marinas #include <asm/unistd.h>
342c020ed8SCatalin Marinas #include <asm/fpsimd.h>
352c020ed8SCatalin Marinas #include <asm/signal32.h>
362c020ed8SCatalin Marinas #include <asm/vdso.h>
372c020ed8SCatalin Marinas 
382c020ed8SCatalin Marinas /*
392c020ed8SCatalin Marinas  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
402c020ed8SCatalin Marinas  */
412c020ed8SCatalin Marinas struct rt_sigframe {
422c020ed8SCatalin Marinas 	struct siginfo info;
432c020ed8SCatalin Marinas 	struct ucontext uc;
44304ef4e8SWill Deacon 	u64 fp;
45304ef4e8SWill Deacon 	u64 lr;
462c020ed8SCatalin Marinas };
472c020ed8SCatalin Marinas 
482c020ed8SCatalin Marinas static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
492c020ed8SCatalin Marinas {
502c020ed8SCatalin Marinas 	struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
512c020ed8SCatalin Marinas 	int err;
522c020ed8SCatalin Marinas 
532c020ed8SCatalin Marinas 	/* dump the hardware registers to the fpsimd_state structure */
54c51f9269SArd Biesheuvel 	fpsimd_preserve_current_state();
552c020ed8SCatalin Marinas 
562c020ed8SCatalin Marinas 	/* copy the FP and status/control registers */
572c020ed8SCatalin Marinas 	err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs));
582c020ed8SCatalin Marinas 	__put_user_error(fpsimd->fpsr, &ctx->fpsr, err);
592c020ed8SCatalin Marinas 	__put_user_error(fpsimd->fpcr, &ctx->fpcr, err);
602c020ed8SCatalin Marinas 
612c020ed8SCatalin Marinas 	/* copy the magic/size information */
622c020ed8SCatalin Marinas 	__put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err);
632c020ed8SCatalin Marinas 	__put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err);
642c020ed8SCatalin Marinas 
652c020ed8SCatalin Marinas 	return err ? -EFAULT : 0;
662c020ed8SCatalin Marinas }
672c020ed8SCatalin Marinas 
682c020ed8SCatalin Marinas static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
692c020ed8SCatalin Marinas {
702c020ed8SCatalin Marinas 	struct fpsimd_state fpsimd;
712c020ed8SCatalin Marinas 	__u32 magic, size;
722c020ed8SCatalin Marinas 	int err = 0;
732c020ed8SCatalin Marinas 
742c020ed8SCatalin Marinas 	/* check the magic/size information */
752c020ed8SCatalin Marinas 	__get_user_error(magic, &ctx->head.magic, err);
762c020ed8SCatalin Marinas 	__get_user_error(size, &ctx->head.size, err);
772c020ed8SCatalin Marinas 	if (err)
782c020ed8SCatalin Marinas 		return -EFAULT;
792c020ed8SCatalin Marinas 	if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context))
802c020ed8SCatalin Marinas 		return -EINVAL;
812c020ed8SCatalin Marinas 
822c020ed8SCatalin Marinas 	/* copy the FP and status/control registers */
832c020ed8SCatalin Marinas 	err = __copy_from_user(fpsimd.vregs, ctx->vregs,
842c020ed8SCatalin Marinas 			       sizeof(fpsimd.vregs));
852c020ed8SCatalin Marinas 	__get_user_error(fpsimd.fpsr, &ctx->fpsr, err);
862c020ed8SCatalin Marinas 	__get_user_error(fpsimd.fpcr, &ctx->fpcr, err);
872c020ed8SCatalin Marinas 
882c020ed8SCatalin Marinas 	/* load the hardware registers from the fpsimd_state structure */
89c51f9269SArd Biesheuvel 	if (!err)
90c51f9269SArd Biesheuvel 		fpsimd_update_current_state(&fpsimd);
912c020ed8SCatalin Marinas 
922c020ed8SCatalin Marinas 	return err ? -EFAULT : 0;
932c020ed8SCatalin Marinas }
942c020ed8SCatalin Marinas 
952c020ed8SCatalin Marinas static int restore_sigframe(struct pt_regs *regs,
962c020ed8SCatalin Marinas 			    struct rt_sigframe __user *sf)
972c020ed8SCatalin Marinas {
982c020ed8SCatalin Marinas 	sigset_t set;
992c020ed8SCatalin Marinas 	int i, err;
1000e0276d1SCatalin Marinas 	void *aux = sf->uc.uc_mcontext.__reserved;
1012c020ed8SCatalin Marinas 
1022c020ed8SCatalin Marinas 	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
1032c020ed8SCatalin Marinas 	if (err == 0)
1042c020ed8SCatalin Marinas 		set_current_blocked(&set);
1052c020ed8SCatalin Marinas 
1062c020ed8SCatalin Marinas 	for (i = 0; i < 31; i++)
1072c020ed8SCatalin Marinas 		__get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i],
1082c020ed8SCatalin Marinas 				 err);
1092c020ed8SCatalin Marinas 	__get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err);
1102c020ed8SCatalin Marinas 	__get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err);
1112c020ed8SCatalin Marinas 	__get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err);
1122c020ed8SCatalin Marinas 
1132c020ed8SCatalin Marinas 	/*
1142c020ed8SCatalin Marinas 	 * Avoid sys_rt_sigreturn() restarting.
1152c020ed8SCatalin Marinas 	 */
1162c020ed8SCatalin Marinas 	regs->syscallno = ~0UL;
1172c020ed8SCatalin Marinas 
118dbd4d7caSMark Rutland 	err |= !valid_user_regs(&regs->user_regs, current);
1192c020ed8SCatalin Marinas 
1200e0276d1SCatalin Marinas 	if (err == 0) {
1210e0276d1SCatalin Marinas 		struct fpsimd_context *fpsimd_ctx =
1220e0276d1SCatalin Marinas 			container_of(aux, struct fpsimd_context, head);
1230e0276d1SCatalin Marinas 		err |= restore_fpsimd_context(fpsimd_ctx);
1240e0276d1SCatalin Marinas 	}
1252c020ed8SCatalin Marinas 
1262c020ed8SCatalin Marinas 	return err;
1272c020ed8SCatalin Marinas }
1282c020ed8SCatalin Marinas 
1292c020ed8SCatalin Marinas asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
1302c020ed8SCatalin Marinas {
1312c020ed8SCatalin Marinas 	struct rt_sigframe __user *frame;
1322c020ed8SCatalin Marinas 
1332c020ed8SCatalin Marinas 	/* Always make any pending restarted system calls return -EINTR */
134f56141e3SAndy Lutomirski 	current->restart_block.fn = do_no_restart_syscall;
1352c020ed8SCatalin Marinas 
1362c020ed8SCatalin Marinas 	/*
1372c020ed8SCatalin Marinas 	 * Since we stacked the signal on a 128-bit boundary, then 'sp' should
1382c020ed8SCatalin Marinas 	 * be word aligned here.
1392c020ed8SCatalin Marinas 	 */
1402c020ed8SCatalin Marinas 	if (regs->sp & 15)
1412c020ed8SCatalin Marinas 		goto badframe;
1422c020ed8SCatalin Marinas 
1432c020ed8SCatalin Marinas 	frame = (struct rt_sigframe __user *)regs->sp;
1442c020ed8SCatalin Marinas 
1452c020ed8SCatalin Marinas 	if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
1462c020ed8SCatalin Marinas 		goto badframe;
1472c020ed8SCatalin Marinas 
1482c020ed8SCatalin Marinas 	if (restore_sigframe(regs, frame))
1492c020ed8SCatalin Marinas 		goto badframe;
1502c020ed8SCatalin Marinas 
151207bdae4SAl Viro 	if (restore_altstack(&frame->uc.uc_stack))
1522c020ed8SCatalin Marinas 		goto badframe;
1532c020ed8SCatalin Marinas 
1542c020ed8SCatalin Marinas 	return regs->regs[0];
1552c020ed8SCatalin Marinas 
1562c020ed8SCatalin Marinas badframe:
1572c020ed8SCatalin Marinas 	if (show_unhandled_signals)
1582c020ed8SCatalin Marinas 		pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",
1592c020ed8SCatalin Marinas 				    current->comm, task_pid_nr(current), __func__,
1602c020ed8SCatalin Marinas 				    regs->pc, regs->sp);
1612c020ed8SCatalin Marinas 	force_sig(SIGSEGV, current);
1622c020ed8SCatalin Marinas 	return 0;
1632c020ed8SCatalin Marinas }
1642c020ed8SCatalin Marinas 
1652c020ed8SCatalin Marinas static int setup_sigframe(struct rt_sigframe __user *sf,
1662c020ed8SCatalin Marinas 			  struct pt_regs *regs, sigset_t *set)
1672c020ed8SCatalin Marinas {
1682c020ed8SCatalin Marinas 	int i, err = 0;
1690e0276d1SCatalin Marinas 	void *aux = sf->uc.uc_mcontext.__reserved;
1700e0276d1SCatalin Marinas 	struct _aarch64_ctx *end;
1712c020ed8SCatalin Marinas 
172304ef4e8SWill Deacon 	/* set up the stack frame for unwinding */
173304ef4e8SWill Deacon 	__put_user_error(regs->regs[29], &sf->fp, err);
174304ef4e8SWill Deacon 	__put_user_error(regs->regs[30], &sf->lr, err);
175304ef4e8SWill Deacon 
1762c020ed8SCatalin Marinas 	for (i = 0; i < 31; i++)
1772c020ed8SCatalin Marinas 		__put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i],
1782c020ed8SCatalin Marinas 				 err);
1792c020ed8SCatalin Marinas 	__put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err);
1802c020ed8SCatalin Marinas 	__put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err);
1812c020ed8SCatalin Marinas 	__put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err);
1822c020ed8SCatalin Marinas 
1832c020ed8SCatalin Marinas 	__put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err);
1842c020ed8SCatalin Marinas 
1852c020ed8SCatalin Marinas 	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
1862c020ed8SCatalin Marinas 
1870e0276d1SCatalin Marinas 	if (err == 0) {
1880e0276d1SCatalin Marinas 		struct fpsimd_context *fpsimd_ctx =
1890e0276d1SCatalin Marinas 			container_of(aux, struct fpsimd_context, head);
1900e0276d1SCatalin Marinas 		err |= preserve_fpsimd_context(fpsimd_ctx);
1910e0276d1SCatalin Marinas 		aux += sizeof(*fpsimd_ctx);
1920e0276d1SCatalin Marinas 	}
1932c020ed8SCatalin Marinas 
19415af1942SCatalin Marinas 	/* fault information, if valid */
19515af1942SCatalin Marinas 	if (current->thread.fault_code) {
19615af1942SCatalin Marinas 		struct esr_context *esr_ctx =
19715af1942SCatalin Marinas 			container_of(aux, struct esr_context, head);
19815af1942SCatalin Marinas 		__put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err);
19915af1942SCatalin Marinas 		__put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err);
20015af1942SCatalin Marinas 		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
20115af1942SCatalin Marinas 		aux += sizeof(*esr_ctx);
20215af1942SCatalin Marinas 	}
20315af1942SCatalin Marinas 
2042c020ed8SCatalin Marinas 	/* set the "end" magic */
2050e0276d1SCatalin Marinas 	end = aux;
2060e0276d1SCatalin Marinas 	__put_user_error(0, &end->magic, err);
2070e0276d1SCatalin Marinas 	__put_user_error(0, &end->size, err);
2082c020ed8SCatalin Marinas 
2092c020ed8SCatalin Marinas 	return err;
2102c020ed8SCatalin Marinas }
2112c020ed8SCatalin Marinas 
21238a7be3cSRichard Weinberger static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
213b64e1c61SWill Deacon 					       struct pt_regs *regs)
2142c020ed8SCatalin Marinas {
2152c020ed8SCatalin Marinas 	unsigned long sp, sp_top;
216b64e1c61SWill Deacon 	struct rt_sigframe __user *frame;
2172c020ed8SCatalin Marinas 
21838a7be3cSRichard Weinberger 	sp = sp_top = sigsp(regs->sp, ksig);
2192c020ed8SCatalin Marinas 
220b64e1c61SWill Deacon 	sp = (sp - sizeof(struct rt_sigframe)) & ~15;
221b64e1c61SWill Deacon 	frame = (struct rt_sigframe __user *)sp;
2222c020ed8SCatalin Marinas 
2232c020ed8SCatalin Marinas 	/*
2242c020ed8SCatalin Marinas 	 * Check that we can actually write to the signal frame.
2252c020ed8SCatalin Marinas 	 */
2262c020ed8SCatalin Marinas 	if (!access_ok(VERIFY_WRITE, frame, sp_top - sp))
2272c020ed8SCatalin Marinas 		frame = NULL;
2282c020ed8SCatalin Marinas 
2292c020ed8SCatalin Marinas 	return frame;
2302c020ed8SCatalin Marinas }
2312c020ed8SCatalin Marinas 
232304ef4e8SWill Deacon static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
2332c020ed8SCatalin Marinas 			 void __user *frame, int usig)
2342c020ed8SCatalin Marinas {
2352c020ed8SCatalin Marinas 	__sigrestore_t sigtramp;
2362c020ed8SCatalin Marinas 
2372c020ed8SCatalin Marinas 	regs->regs[0] = usig;
2382c020ed8SCatalin Marinas 	regs->sp = (unsigned long)frame;
239304ef4e8SWill Deacon 	regs->regs[29] = regs->sp + offsetof(struct rt_sigframe, fp);
2402c020ed8SCatalin Marinas 	regs->pc = (unsigned long)ka->sa.sa_handler;
2412c020ed8SCatalin Marinas 
2422c020ed8SCatalin Marinas 	if (ka->sa.sa_flags & SA_RESTORER)
2432c020ed8SCatalin Marinas 		sigtramp = ka->sa.sa_restorer;
2442c020ed8SCatalin Marinas 	else
2452c020ed8SCatalin Marinas 		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
2462c020ed8SCatalin Marinas 
2472c020ed8SCatalin Marinas 	regs->regs[30] = (unsigned long)sigtramp;
2482c020ed8SCatalin Marinas }
2492c020ed8SCatalin Marinas 
25000554fa4SRichard Weinberger static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
25100554fa4SRichard Weinberger 			  struct pt_regs *regs)
2522c020ed8SCatalin Marinas {
2532c020ed8SCatalin Marinas 	struct rt_sigframe __user *frame;
2542c020ed8SCatalin Marinas 	int err = 0;
2552c020ed8SCatalin Marinas 
25638a7be3cSRichard Weinberger 	frame = get_sigframe(ksig, regs);
2572c020ed8SCatalin Marinas 	if (!frame)
2582c020ed8SCatalin Marinas 		return 1;
2592c020ed8SCatalin Marinas 
2602c020ed8SCatalin Marinas 	__put_user_error(0, &frame->uc.uc_flags, err);
2612c020ed8SCatalin Marinas 	__put_user_error(NULL, &frame->uc.uc_link, err);
2622c020ed8SCatalin Marinas 
263207bdae4SAl Viro 	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
2642c020ed8SCatalin Marinas 	err |= setup_sigframe(frame, regs, set);
265304ef4e8SWill Deacon 	if (err == 0) {
26600554fa4SRichard Weinberger 		setup_return(regs, &ksig->ka, frame, usig);
26700554fa4SRichard Weinberger 		if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
26800554fa4SRichard Weinberger 			err |= copy_siginfo_to_user(&frame->info, &ksig->info);
2692c020ed8SCatalin Marinas 			regs->regs[1] = (unsigned long)&frame->info;
2702c020ed8SCatalin Marinas 			regs->regs[2] = (unsigned long)&frame->uc;
2712c020ed8SCatalin Marinas 		}
272304ef4e8SWill Deacon 	}
2732c020ed8SCatalin Marinas 
2742c020ed8SCatalin Marinas 	return err;
2752c020ed8SCatalin Marinas }
2762c020ed8SCatalin Marinas 
2772c020ed8SCatalin Marinas static void setup_restart_syscall(struct pt_regs *regs)
2782c020ed8SCatalin Marinas {
2792c020ed8SCatalin Marinas 	if (is_compat_task())
2802c020ed8SCatalin Marinas 		compat_setup_restart_syscall(regs);
2812c020ed8SCatalin Marinas 	else
2822c020ed8SCatalin Marinas 		regs->regs[8] = __NR_restart_syscall;
2832c020ed8SCatalin Marinas }
2842c020ed8SCatalin Marinas 
2852c020ed8SCatalin Marinas /*
2862c020ed8SCatalin Marinas  * OK, we're invoking a handler
2872c020ed8SCatalin Marinas  */
28800554fa4SRichard Weinberger static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
2892c020ed8SCatalin Marinas {
2902c020ed8SCatalin Marinas 	struct task_struct *tsk = current;
2912c020ed8SCatalin Marinas 	sigset_t *oldset = sigmask_to_save();
29200554fa4SRichard Weinberger 	int usig = ksig->sig;
2932c020ed8SCatalin Marinas 	int ret;
2942c020ed8SCatalin Marinas 
2952c020ed8SCatalin Marinas 	/*
2962c020ed8SCatalin Marinas 	 * Set up the stack frame
2972c020ed8SCatalin Marinas 	 */
2982c020ed8SCatalin Marinas 	if (is_compat_task()) {
29900554fa4SRichard Weinberger 		if (ksig->ka.sa.sa_flags & SA_SIGINFO)
30000554fa4SRichard Weinberger 			ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
3012c020ed8SCatalin Marinas 		else
30200554fa4SRichard Weinberger 			ret = compat_setup_frame(usig, ksig, oldset, regs);
3032c020ed8SCatalin Marinas 	} else {
30400554fa4SRichard Weinberger 		ret = setup_rt_frame(usig, ksig, oldset, regs);
3052c020ed8SCatalin Marinas 	}
3062c020ed8SCatalin Marinas 
3072c020ed8SCatalin Marinas 	/*
3082c020ed8SCatalin Marinas 	 * Check that the resulting registers are actually sane.
3092c020ed8SCatalin Marinas 	 */
310dbd4d7caSMark Rutland 	ret |= !valid_user_regs(&regs->user_regs, current);
3112c020ed8SCatalin Marinas 
3122c020ed8SCatalin Marinas 	/*
3132c020ed8SCatalin Marinas 	 * Fast forward the stepping logic so we step into the signal
3142c020ed8SCatalin Marinas 	 * handler.
3152c020ed8SCatalin Marinas 	 */
31600554fa4SRichard Weinberger 	if (!ret)
3172c020ed8SCatalin Marinas 		user_fastforward_single_step(tsk);
3182c020ed8SCatalin Marinas 
31900554fa4SRichard Weinberger 	signal_setup_done(ret, ksig, 0);
3202c020ed8SCatalin Marinas }
3212c020ed8SCatalin Marinas 
3222c020ed8SCatalin Marinas /*
3232c020ed8SCatalin Marinas  * Note that 'init' is a special process: it doesn't get signals it doesn't
3242c020ed8SCatalin Marinas  * want to handle. Thus you cannot kill init even with a SIGKILL even by
3252c020ed8SCatalin Marinas  * mistake.
3262c020ed8SCatalin Marinas  *
3272c020ed8SCatalin Marinas  * Note that we go through the signals twice: once to check the signals that
3282c020ed8SCatalin Marinas  * the kernel can handle, and then we build all the user-level signal handling
3292c020ed8SCatalin Marinas  * stack-frames in one go after that.
3302c020ed8SCatalin Marinas  */
3312c020ed8SCatalin Marinas static void do_signal(struct pt_regs *regs)
3322c020ed8SCatalin Marinas {
3332c020ed8SCatalin Marinas 	unsigned long continue_addr = 0, restart_addr = 0;
33400554fa4SRichard Weinberger 	int retval = 0;
3352c020ed8SCatalin Marinas 	int syscall = (int)regs->syscallno;
33600554fa4SRichard Weinberger 	struct ksignal ksig;
3372c020ed8SCatalin Marinas 
3382c020ed8SCatalin Marinas 	/*
3392c020ed8SCatalin Marinas 	 * If we were from a system call, check for system call restarting...
3402c020ed8SCatalin Marinas 	 */
3412c020ed8SCatalin Marinas 	if (syscall >= 0) {
3422c020ed8SCatalin Marinas 		continue_addr = regs->pc;
3432c020ed8SCatalin Marinas 		restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4);
3442c020ed8SCatalin Marinas 		retval = regs->regs[0];
3452c020ed8SCatalin Marinas 
3462c020ed8SCatalin Marinas 		/*
3472c020ed8SCatalin Marinas 		 * Avoid additional syscall restarting via ret_to_user.
3482c020ed8SCatalin Marinas 		 */
3492c020ed8SCatalin Marinas 		regs->syscallno = ~0UL;
3502c020ed8SCatalin Marinas 
3512c020ed8SCatalin Marinas 		/*
3522c020ed8SCatalin Marinas 		 * Prepare for system call restart. We do this here so that a
3532c020ed8SCatalin Marinas 		 * debugger will see the already changed PC.
3542c020ed8SCatalin Marinas 		 */
3552c020ed8SCatalin Marinas 		switch (retval) {
3562c020ed8SCatalin Marinas 		case -ERESTARTNOHAND:
3572c020ed8SCatalin Marinas 		case -ERESTARTSYS:
3582c020ed8SCatalin Marinas 		case -ERESTARTNOINTR:
3592c020ed8SCatalin Marinas 		case -ERESTART_RESTARTBLOCK:
3602c020ed8SCatalin Marinas 			regs->regs[0] = regs->orig_x0;
3612c020ed8SCatalin Marinas 			regs->pc = restart_addr;
3622c020ed8SCatalin Marinas 			break;
3632c020ed8SCatalin Marinas 		}
3642c020ed8SCatalin Marinas 	}
3652c020ed8SCatalin Marinas 
3662c020ed8SCatalin Marinas 	/*
3672c020ed8SCatalin Marinas 	 * Get the signal to deliver. When running under ptrace, at this point
3682c020ed8SCatalin Marinas 	 * the debugger may change all of our registers.
3692c020ed8SCatalin Marinas 	 */
37000554fa4SRichard Weinberger 	if (get_signal(&ksig)) {
3712c020ed8SCatalin Marinas 		/*
3722c020ed8SCatalin Marinas 		 * Depending on the signal settings, we may need to revert the
3732c020ed8SCatalin Marinas 		 * decision to restart the system call, but skip this if a
3742c020ed8SCatalin Marinas 		 * debugger has chosen to restart at a different PC.
3752c020ed8SCatalin Marinas 		 */
3762c020ed8SCatalin Marinas 		if (regs->pc == restart_addr &&
3772c020ed8SCatalin Marinas 		    (retval == -ERESTARTNOHAND ||
3782c020ed8SCatalin Marinas 		     retval == -ERESTART_RESTARTBLOCK ||
3792c020ed8SCatalin Marinas 		     (retval == -ERESTARTSYS &&
38000554fa4SRichard Weinberger 		      !(ksig.ka.sa.sa_flags & SA_RESTART)))) {
3812c020ed8SCatalin Marinas 			regs->regs[0] = -EINTR;
3822c020ed8SCatalin Marinas 			regs->pc = continue_addr;
3832c020ed8SCatalin Marinas 		}
3842c020ed8SCatalin Marinas 
38500554fa4SRichard Weinberger 		handle_signal(&ksig, regs);
3862c020ed8SCatalin Marinas 		return;
3872c020ed8SCatalin Marinas 	}
3882c020ed8SCatalin Marinas 
3892c020ed8SCatalin Marinas 	/*
3902c020ed8SCatalin Marinas 	 * Handle restarting a different system call. As above, if a debugger
3912c020ed8SCatalin Marinas 	 * has chosen to restart at a different PC, ignore the restart.
3922c020ed8SCatalin Marinas 	 */
3932c020ed8SCatalin Marinas 	if (syscall >= 0 && regs->pc == restart_addr) {
3942c020ed8SCatalin Marinas 		if (retval == -ERESTART_RESTARTBLOCK)
3952c020ed8SCatalin Marinas 			setup_restart_syscall(regs);
3962c020ed8SCatalin Marinas 		user_rewind_single_step(current);
3972c020ed8SCatalin Marinas 	}
3982c020ed8SCatalin Marinas 
3992c020ed8SCatalin Marinas 	restore_saved_sigmask();
4002c020ed8SCatalin Marinas }
4012c020ed8SCatalin Marinas 
4022c020ed8SCatalin Marinas asmlinkage void do_notify_resume(struct pt_regs *regs,
4032c020ed8SCatalin Marinas 				 unsigned int thread_flags)
4042c020ed8SCatalin Marinas {
405421dd6faSChris Metcalf 	/*
406421dd6faSChris Metcalf 	 * The assembly code enters us with IRQs off, but it hasn't
407421dd6faSChris Metcalf 	 * informed the tracing code of that for efficiency reasons.
408421dd6faSChris Metcalf 	 * Update the trace code with the current status.
409421dd6faSChris Metcalf 	 */
410421dd6faSChris Metcalf 	trace_hardirqs_off();
411421dd6faSChris Metcalf 	do {
412421dd6faSChris Metcalf 		if (thread_flags & _TIF_NEED_RESCHED) {
413421dd6faSChris Metcalf 			schedule();
414421dd6faSChris Metcalf 		} else {
415421dd6faSChris Metcalf 			local_irq_enable();
416421dd6faSChris Metcalf 
4179842ceaeSPratyush Anand 			if (thread_flags & _TIF_UPROBE)
4189842ceaeSPratyush Anand 				uprobe_notify_resume(regs);
4199842ceaeSPratyush Anand 
4202c020ed8SCatalin Marinas 			if (thread_flags & _TIF_SIGPENDING)
4212c020ed8SCatalin Marinas 				do_signal(regs);
4222c020ed8SCatalin Marinas 
4232c020ed8SCatalin Marinas 			if (thread_flags & _TIF_NOTIFY_RESUME) {
4242c020ed8SCatalin Marinas 				clear_thread_flag(TIF_NOTIFY_RESUME);
4252c020ed8SCatalin Marinas 				tracehook_notify_resume(regs);
4262c020ed8SCatalin Marinas 			}
427005f78cdSArd Biesheuvel 
428005f78cdSArd Biesheuvel 			if (thread_flags & _TIF_FOREIGN_FPSTATE)
429005f78cdSArd Biesheuvel 				fpsimd_restore_current_state();
430421dd6faSChris Metcalf 		}
431005f78cdSArd Biesheuvel 
432421dd6faSChris Metcalf 		local_irq_disable();
433421dd6faSChris Metcalf 		thread_flags = READ_ONCE(current_thread_info()->flags);
434421dd6faSChris Metcalf 	} while (thread_flags & _TIF_WORK_MASK);
4352c020ed8SCatalin Marinas }
436