1e9564df7SGuo Ren // SPDX-License-Identifier: GPL-2.0 2e9564df7SGuo Ren 3e9564df7SGuo Ren #include <linux/signal.h> 4e9564df7SGuo Ren #include <linux/uaccess.h> 5bf241682SGuo Ren #include <linux/syscalls.h> 6*03248addSEric W. Biederman #include <linux/resume_user_mode.h> 7e9564df7SGuo Ren 8e9564df7SGuo Ren #include <asm/traps.h> 9e9564df7SGuo Ren #include <asm/ucontext.h> 10e9564df7SGuo Ren #include <asm/vdso.h> 11e9564df7SGuo Ren 12e9564df7SGuo Ren #include <abi/regdef.h> 13e9564df7SGuo Ren 14e9564df7SGuo Ren #ifdef CONFIG_CPU_HAS_FPU 15e9564df7SGuo Ren #include <abi/fpu.h> 16bf241682SGuo Ren static int restore_fpu_state(struct sigcontext __user *sc) 17e9564df7SGuo Ren { 18e9564df7SGuo Ren int err = 0; 19e9564df7SGuo Ren struct user_fp user_fp; 20e9564df7SGuo Ren 21bf241682SGuo Ren err = __copy_from_user(&user_fp, &sc->sc_user_fp, sizeof(user_fp)); 22e9564df7SGuo Ren 23e9564df7SGuo Ren restore_from_user_fp(&user_fp); 24e9564df7SGuo Ren 25e9564df7SGuo Ren return err; 26e9564df7SGuo Ren } 27e9564df7SGuo Ren 28bf241682SGuo Ren static int save_fpu_state(struct sigcontext __user *sc) 29e9564df7SGuo Ren { 30e9564df7SGuo Ren struct user_fp user_fp; 31e9564df7SGuo Ren 32e9564df7SGuo Ren save_to_user_fp(&user_fp); 33e9564df7SGuo Ren 34bf241682SGuo Ren return __copy_to_user(&sc->sc_user_fp, &user_fp, sizeof(user_fp)); 35e9564df7SGuo Ren } 36e9564df7SGuo Ren #else 37bf241682SGuo Ren #define restore_fpu_state(sigcontext) (0) 38bf241682SGuo Ren #define save_fpu_state(sigcontext) (0) 39e9564df7SGuo Ren #endif 40e9564df7SGuo Ren 41e9564df7SGuo Ren struct rt_sigframe { 4219e5e2aeSGuo Ren /* 4319e5e2aeSGuo Ren * pad[3] is compatible with the same struct defined in 4419e5e2aeSGuo Ren * gcc/libgcc/config/csky/linux-unwind.h 4519e5e2aeSGuo Ren */ 4619e5e2aeSGuo Ren int pad[3]; 47e9564df7SGuo Ren struct siginfo info; 48e9564df7SGuo Ren struct ucontext uc; 49e9564df7SGuo Ren }; 50e9564df7SGuo Ren 51bf241682SGuo Ren static long restore_sigcontext(struct pt_regs *regs, 52bf241682SGuo Ren struct sigcontext __user *sc) 53e9564df7SGuo Ren { 54e9564df7SGuo Ren int err = 0; 55fbd63c08SAl Viro unsigned long sr = regs->sr; 56e9564df7SGuo Ren 57bf241682SGuo Ren /* sc_pt_regs is structured the same as the start of pt_regs */ 58bf241682SGuo Ren err |= __copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs)); 59e9564df7SGuo Ren 60fbd63c08SAl Viro /* BIT(0) of regs->sr is Condition Code/Carry bit */ 61fbd63c08SAl Viro regs->sr = (sr & ~1) | (regs->sr & 1); 62fbd63c08SAl Viro 63bf241682SGuo Ren /* Restore the floating-point state. */ 64e9564df7SGuo Ren err |= restore_fpu_state(sc); 65e9564df7SGuo Ren 66e9564df7SGuo Ren return err; 67e9564df7SGuo Ren } 68e9564df7SGuo Ren 69bf241682SGuo Ren SYSCALL_DEFINE0(rt_sigreturn) 70e9564df7SGuo Ren { 71e9564df7SGuo Ren struct pt_regs *regs = current_pt_regs(); 72bf241682SGuo Ren struct rt_sigframe __user *frame; 73bf241682SGuo Ren sigset_t set; 74bf241682SGuo Ren 75bf241682SGuo Ren /* Always make any pending restarted system calls return -EINTR */ 76bf241682SGuo Ren current->restart_block.fn = do_no_restart_syscall; 77bf241682SGuo Ren 78bf241682SGuo Ren frame = (struct rt_sigframe __user *)regs->usp; 79e9564df7SGuo Ren 8096d4f267SLinus Torvalds if (!access_ok(frame, sizeof(*frame))) 81e9564df7SGuo Ren goto badframe; 82bf241682SGuo Ren 83e9564df7SGuo Ren if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 84e9564df7SGuo Ren goto badframe; 85e9564df7SGuo Ren 86bf241682SGuo Ren set_current_blocked(&set); 87e9564df7SGuo Ren 88bf241682SGuo Ren if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 89e9564df7SGuo Ren goto badframe; 90e9564df7SGuo Ren 91bf241682SGuo Ren if (restore_altstack(&frame->uc.uc_stack)) 92bf241682SGuo Ren goto badframe; 93bf241682SGuo Ren 94bf241682SGuo Ren return regs->a0; 95e9564df7SGuo Ren 96e9564df7SGuo Ren badframe: 973cf5d076SEric W. Biederman force_sig(SIGSEGV); 98e9564df7SGuo Ren return 0; 99e9564df7SGuo Ren } 100e9564df7SGuo Ren 101bf241682SGuo Ren static int setup_sigcontext(struct rt_sigframe __user *frame, 102bf241682SGuo Ren struct pt_regs *regs) 103e9564df7SGuo Ren { 104bf241682SGuo Ren struct sigcontext __user *sc = &frame->uc.uc_mcontext; 105e9564df7SGuo Ren int err = 0; 106e9564df7SGuo Ren 107bf241682SGuo Ren err |= __copy_to_user(&sc->sc_pt_regs, regs, sizeof(struct pt_regs)); 108e9564df7SGuo Ren err |= save_fpu_state(sc); 109e9564df7SGuo Ren 110e9564df7SGuo Ren return err; 111e9564df7SGuo Ren } 112e9564df7SGuo Ren 113bf241682SGuo Ren static inline void __user *get_sigframe(struct ksignal *ksig, 114bf241682SGuo Ren struct pt_regs *regs, size_t framesize) 115e9564df7SGuo Ren { 116bf241682SGuo Ren unsigned long sp; 117bf241682SGuo Ren /* Default to using normal stack */ 118bf241682SGuo Ren sp = regs->usp; 119e9564df7SGuo Ren 120bf241682SGuo Ren /* 121bf241682SGuo Ren * If we are on the alternate signal stack and would overflow it, don't. 122bf241682SGuo Ren * Return an always-bogus address instead so we will die with SIGSEGV. 123bf241682SGuo Ren */ 124bf241682SGuo Ren if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) 125bf241682SGuo Ren return (void __user __force *)(-1UL); 126e9564df7SGuo Ren 127e9564df7SGuo Ren /* This is the X/Open sanctioned signal stack switching. */ 128bf241682SGuo Ren sp = sigsp(sp, ksig) - framesize; 129bf241682SGuo Ren 130bf241682SGuo Ren /* Align the stack frame. */ 131bf241682SGuo Ren sp &= -8UL; 132bf241682SGuo Ren 133bf241682SGuo Ren return (void __user *)sp; 134e9564df7SGuo Ren } 135e9564df7SGuo Ren 136e9564df7SGuo Ren static int 137e9564df7SGuo Ren setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) 138e9564df7SGuo Ren { 13923fc539eSArnd Bergmann struct rt_sigframe __user *frame; 140e9564df7SGuo Ren int err = 0; 141e9564df7SGuo Ren 142bf241682SGuo Ren frame = get_sigframe(ksig, regs, sizeof(*frame)); 143bf241682SGuo Ren if (!access_ok(frame, sizeof(*frame))) 144bf241682SGuo Ren return -EFAULT; 145e9564df7SGuo Ren 146e9564df7SGuo Ren err |= copy_siginfo_to_user(&frame->info, &ksig->info); 147e9564df7SGuo Ren 148e9564df7SGuo Ren /* Create the ucontext. */ 149e9564df7SGuo Ren err |= __put_user(0, &frame->uc.uc_flags); 150bf241682SGuo Ren err |= __put_user(NULL, &frame->uc.uc_link); 151bf241682SGuo Ren err |= __save_altstack(&frame->uc.uc_stack, regs->usp); 152bf241682SGuo Ren err |= setup_sigcontext(frame, regs); 153bf241682SGuo Ren err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 154e9564df7SGuo Ren if (err) 155bf241682SGuo Ren return -EFAULT; 156e9564df7SGuo Ren 157bf241682SGuo Ren /* Set up to return from userspace. */ 15887f3248cSGuo Ren regs->lr = (unsigned long)VDSO_SYMBOL( 15987f3248cSGuo Ren current->mm->context.vdso, rt_sigreturn); 160bf241682SGuo Ren 161bf241682SGuo Ren /* 162bf241682SGuo Ren * Set up registers for signal handler. 163bf241682SGuo Ren * Registers that we don't modify keep the value they had from 164bf241682SGuo Ren * user-space at the time we took the signal. 165bf241682SGuo Ren * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 166bf241682SGuo Ren * since some things rely on this (e.g. glibc's debug/segfault.c). 167bf241682SGuo Ren */ 168e9564df7SGuo Ren regs->pc = (unsigned long)ksig->ka.sa.sa_handler; 169bf241682SGuo Ren regs->usp = (unsigned long)frame; 170bf241682SGuo Ren regs->a0 = ksig->sig; /* a0: signal number */ 171bf241682SGuo Ren regs->a1 = (unsigned long)(&(frame->info)); /* a1: siginfo pointer */ 172bf241682SGuo Ren regs->a2 = (unsigned long)(&(frame->uc)); /* a2: ucontext pointer */ 173e9564df7SGuo Ren 174e9564df7SGuo Ren return 0; 175e9564df7SGuo Ren } 176e9564df7SGuo Ren 177bf241682SGuo Ren static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 178e9564df7SGuo Ren { 179bf241682SGuo Ren sigset_t *oldset = sigmask_to_save(); 180bf241682SGuo Ren int ret; 181e9564df7SGuo Ren 1829866d141SGuo Ren rseq_signal_deliver(ksig, regs); 1839866d141SGuo Ren 184bf241682SGuo Ren /* Are we from a system call? */ 185f4625ee0SGuo Ren if (in_syscall(regs)) { 186bf241682SGuo Ren /* Avoid additional syscall restarting via ret_from_exception */ 187f4625ee0SGuo Ren forget_syscall(regs); 188f4625ee0SGuo Ren 189bf241682SGuo Ren /* If so, check system call restarting.. */ 190bf241682SGuo Ren switch (regs->a0) { 191bf241682SGuo Ren case -ERESTART_RESTARTBLOCK: 192bf241682SGuo Ren case -ERESTARTNOHAND: 193bf241682SGuo Ren regs->a0 = -EINTR; 194bf241682SGuo Ren break; 195bf241682SGuo Ren 196bf241682SGuo Ren case -ERESTARTSYS: 197bf241682SGuo Ren if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { 198bf241682SGuo Ren regs->a0 = -EINTR; 199bf241682SGuo Ren break; 200bf241682SGuo Ren } 201df561f66SGustavo A. R. Silva fallthrough; 202bf241682SGuo Ren case -ERESTARTNOINTR: 203bf241682SGuo Ren regs->a0 = regs->orig_a0; 204bf241682SGuo Ren regs->pc -= TRAP0_SIZE; 205bf241682SGuo Ren break; 206bf241682SGuo Ren } 207bf241682SGuo Ren } 208bf241682SGuo Ren 209bf241682SGuo Ren /* Set up the stack frame */ 210bf241682SGuo Ren ret = setup_rt_frame(ksig, oldset, regs); 211bf241682SGuo Ren 212bf241682SGuo Ren signal_setup_done(ret, ksig, 0); 213bf241682SGuo Ren } 214bf241682SGuo Ren 215bf241682SGuo Ren static void do_signal(struct pt_regs *regs) 216bf241682SGuo Ren { 217bf241682SGuo Ren struct ksignal ksig; 218bf241682SGuo Ren 219bf241682SGuo Ren if (get_signal(&ksig)) { 220bf241682SGuo Ren /* Actually deliver the signal */ 221bf241682SGuo Ren handle_signal(&ksig, regs); 222bf241682SGuo Ren return; 223bf241682SGuo Ren } 224bf241682SGuo Ren 225bf241682SGuo Ren /* Did we come from a system call? */ 226bf241682SGuo Ren if (in_syscall(regs)) { 227bf241682SGuo Ren /* Avoid additional syscall restarting via ret_from_exception */ 228bf241682SGuo Ren forget_syscall(regs); 229bf241682SGuo Ren 230bf241682SGuo Ren /* Restart the system call - no handlers present */ 231bf241682SGuo Ren switch (regs->a0) { 232e9564df7SGuo Ren case -ERESTARTNOHAND: 233e9564df7SGuo Ren case -ERESTARTSYS: 234e9564df7SGuo Ren case -ERESTARTNOINTR: 235e9564df7SGuo Ren regs->a0 = regs->orig_a0; 236bf241682SGuo Ren regs->pc -= TRAP0_SIZE; 237e9564df7SGuo Ren break; 238e9564df7SGuo Ren case -ERESTART_RESTARTBLOCK: 239bf241682SGuo Ren regs->a0 = regs->orig_a0; 240bf241682SGuo Ren regs_syscallid(regs) = __NR_restart_syscall; 241bf241682SGuo Ren regs->pc -= TRAP0_SIZE; 242e9564df7SGuo Ren break; 243e9564df7SGuo Ren } 244e9564df7SGuo Ren } 245e9564df7SGuo Ren 246e9564df7SGuo Ren /* 247bf241682SGuo Ren * If there is no signal to deliver, we just put the saved 248e9564df7SGuo Ren * sigmask back. 249e9564df7SGuo Ren */ 250bf241682SGuo Ren restore_saved_sigmask(); 251e9564df7SGuo Ren } 252e9564df7SGuo Ren 253bf241682SGuo Ren /* 254bf241682SGuo Ren * notification of userspace execution resumption 255bf241682SGuo Ren * - triggered by the _TIF_WORK_MASK flags 256bf241682SGuo Ren */ 257bf241682SGuo Ren asmlinkage void do_notify_resume(struct pt_regs *regs, 258bf241682SGuo Ren unsigned long thread_info_flags) 259e9564df7SGuo Ren { 2608f6bb793SGuo Ren if (thread_info_flags & _TIF_UPROBE) 2618f6bb793SGuo Ren uprobe_notify_resume(regs); 2628f6bb793SGuo Ren 263bf241682SGuo Ren /* Handle pending signal delivery */ 264f3924d76SJens Axboe if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) 265f4625ee0SGuo Ren do_signal(regs); 266e9564df7SGuo Ren 267a68de80fSSean Christopherson if (thread_info_flags & _TIF_NOTIFY_RESUME) 268*03248addSEric W. Biederman resume_user_mode_work(regs); 269e9564df7SGuo Ren } 270