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 = ¤t->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(®s->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(®s->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