1e9564df7SGuo Ren // SPDX-License-Identifier: GPL-2.0 2e9564df7SGuo Ren // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3e9564df7SGuo Ren 4e9564df7SGuo Ren #include <linux/sched.h> 5e9564df7SGuo Ren #include <linux/mm.h> 6e9564df7SGuo Ren #include <linux/kernel.h> 7e9564df7SGuo Ren #include <linux/signal.h> 8e9564df7SGuo Ren #include <linux/syscalls.h> 9e9564df7SGuo Ren #include <linux/errno.h> 10e9564df7SGuo Ren #include <linux/wait.h> 11e9564df7SGuo Ren #include <linux/ptrace.h> 12e9564df7SGuo Ren #include <linux/unistd.h> 13e9564df7SGuo Ren #include <linux/stddef.h> 14e9564df7SGuo Ren #include <linux/highuid.h> 15e9564df7SGuo Ren #include <linux/personality.h> 16e9564df7SGuo Ren #include <linux/tty.h> 17e9564df7SGuo Ren #include <linux/binfmts.h> 18e9564df7SGuo Ren #include <linux/tracehook.h> 19e9564df7SGuo Ren #include <linux/freezer.h> 20e9564df7SGuo Ren #include <linux/uaccess.h> 21e9564df7SGuo Ren 22e9564df7SGuo Ren #include <asm/setup.h> 23e9564df7SGuo Ren #include <asm/pgtable.h> 24e9564df7SGuo Ren #include <asm/traps.h> 25e9564df7SGuo Ren #include <asm/ucontext.h> 26e9564df7SGuo Ren #include <asm/vdso.h> 27e9564df7SGuo Ren 28e9564df7SGuo Ren #include <abi/regdef.h> 29e9564df7SGuo Ren 30e9564df7SGuo Ren #ifdef CONFIG_CPU_HAS_FPU 31e9564df7SGuo Ren #include <abi/fpu.h> 32e9564df7SGuo Ren 33e9564df7SGuo Ren static int restore_fpu_state(struct sigcontext *sc) 34e9564df7SGuo Ren { 35e9564df7SGuo Ren int err = 0; 36e9564df7SGuo Ren struct user_fp user_fp; 37e9564df7SGuo Ren 38e9564df7SGuo Ren err = copy_from_user(&user_fp, &sc->sc_user_fp, sizeof(user_fp)); 39e9564df7SGuo Ren 40e9564df7SGuo Ren restore_from_user_fp(&user_fp); 41e9564df7SGuo Ren 42e9564df7SGuo Ren return err; 43e9564df7SGuo Ren } 44e9564df7SGuo Ren 45e9564df7SGuo Ren static int save_fpu_state(struct sigcontext *sc) 46e9564df7SGuo Ren { 47e9564df7SGuo Ren struct user_fp user_fp; 48e9564df7SGuo Ren 49e9564df7SGuo Ren save_to_user_fp(&user_fp); 50e9564df7SGuo Ren 51e9564df7SGuo Ren return copy_to_user(&sc->sc_user_fp, &user_fp, sizeof(user_fp)); 52e9564df7SGuo Ren } 53e9564df7SGuo Ren #else 54e9564df7SGuo Ren static inline int restore_fpu_state(struct sigcontext *sc) { return 0; } 55e9564df7SGuo Ren static inline int save_fpu_state(struct sigcontext *sc) { return 0; } 56e9564df7SGuo Ren #endif 57e9564df7SGuo Ren 58e9564df7SGuo Ren struct rt_sigframe { 59e9564df7SGuo Ren int sig; 60e9564df7SGuo Ren struct siginfo *pinfo; 61e9564df7SGuo Ren void *puc; 62e9564df7SGuo Ren struct siginfo info; 63e9564df7SGuo Ren struct ucontext uc; 64e9564df7SGuo Ren }; 65e9564df7SGuo Ren 66e9564df7SGuo Ren static int 67e9564df7SGuo Ren restore_sigframe(struct pt_regs *regs, 68e9564df7SGuo Ren struct sigcontext *sc, int *pr2) 69e9564df7SGuo Ren { 70e9564df7SGuo Ren int err = 0; 71e9564df7SGuo Ren 72e9564df7SGuo Ren /* Always make any pending restarted system calls return -EINTR */ 73e9564df7SGuo Ren current_thread_info()->task->restart_block.fn = do_no_restart_syscall; 74e9564df7SGuo Ren 75e9564df7SGuo Ren err |= copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs)); 76e9564df7SGuo Ren 77e9564df7SGuo Ren err |= restore_fpu_state(sc); 78e9564df7SGuo Ren 79e9564df7SGuo Ren *pr2 = regs->a0; 80e9564df7SGuo Ren return err; 81e9564df7SGuo Ren } 82e9564df7SGuo Ren 83e9564df7SGuo Ren asmlinkage int 84e9564df7SGuo Ren do_rt_sigreturn(void) 85e9564df7SGuo Ren { 86e9564df7SGuo Ren sigset_t set; 87e9564df7SGuo Ren int a0; 88e9564df7SGuo Ren struct pt_regs *regs = current_pt_regs(); 89e9564df7SGuo Ren struct rt_sigframe *frame = (struct rt_sigframe *)(regs->usp); 90e9564df7SGuo Ren 91*96d4f267SLinus Torvalds if (!access_ok(frame, sizeof(*frame))) 92e9564df7SGuo Ren goto badframe; 93e9564df7SGuo Ren if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 94e9564df7SGuo Ren goto badframe; 95e9564df7SGuo Ren 96e9564df7SGuo Ren sigdelsetmask(&set, (sigmask(SIGKILL) | sigmask(SIGSTOP))); 97e9564df7SGuo Ren spin_lock_irq(¤t->sighand->siglock); 98e9564df7SGuo Ren current->blocked = set; 99e9564df7SGuo Ren recalc_sigpending(); 100e9564df7SGuo Ren spin_unlock_irq(¤t->sighand->siglock); 101e9564df7SGuo Ren 102e9564df7SGuo Ren if (restore_sigframe(regs, &frame->uc.uc_mcontext, &a0)) 103e9564df7SGuo Ren goto badframe; 104e9564df7SGuo Ren 105e9564df7SGuo Ren return a0; 106e9564df7SGuo Ren 107e9564df7SGuo Ren badframe: 108e9564df7SGuo Ren force_sig(SIGSEGV, current); 109e9564df7SGuo Ren return 0; 110e9564df7SGuo Ren } 111e9564df7SGuo Ren 112e9564df7SGuo Ren static int setup_sigframe(struct sigcontext *sc, struct pt_regs *regs) 113e9564df7SGuo Ren { 114e9564df7SGuo Ren int err = 0; 115e9564df7SGuo Ren 116e9564df7SGuo Ren err |= copy_to_user(&sc->sc_pt_regs, regs, sizeof(struct pt_regs)); 117e9564df7SGuo Ren err |= save_fpu_state(sc); 118e9564df7SGuo Ren 119e9564df7SGuo Ren return err; 120e9564df7SGuo Ren } 121e9564df7SGuo Ren 122e9564df7SGuo Ren static inline void * 123e9564df7SGuo Ren get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 124e9564df7SGuo Ren { 125e9564df7SGuo Ren unsigned long usp; 126e9564df7SGuo Ren 127e9564df7SGuo Ren /* Default to using normal stack. */ 128e9564df7SGuo Ren usp = regs->usp; 129e9564df7SGuo Ren 130e9564df7SGuo Ren /* This is the X/Open sanctioned signal stack switching. */ 131e9564df7SGuo Ren if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(usp)) { 132e9564df7SGuo Ren if (!on_sig_stack(usp)) 133e9564df7SGuo Ren usp = current->sas_ss_sp + current->sas_ss_size; 134e9564df7SGuo Ren } 135e9564df7SGuo Ren return (void *)((usp - frame_size) & -8UL); 136e9564df7SGuo Ren } 137e9564df7SGuo Ren 138e9564df7SGuo Ren static int 139e9564df7SGuo Ren setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) 140e9564df7SGuo Ren { 141e9564df7SGuo Ren struct rt_sigframe *frame; 142e9564df7SGuo Ren int err = 0; 143e9564df7SGuo Ren 144e9564df7SGuo Ren struct csky_vdso *vdso = current->mm->context.vdso; 145e9564df7SGuo Ren 146e9564df7SGuo Ren frame = get_sigframe(&ksig->ka, regs, sizeof(*frame)); 147e9564df7SGuo Ren if (!frame) 148e9564df7SGuo Ren return 1; 149e9564df7SGuo Ren 150e9564df7SGuo Ren err |= __put_user(ksig->sig, &frame->sig); 151e9564df7SGuo Ren err |= __put_user(&frame->info, &frame->pinfo); 152e9564df7SGuo Ren err |= __put_user(&frame->uc, &frame->puc); 153e9564df7SGuo Ren err |= copy_siginfo_to_user(&frame->info, &ksig->info); 154e9564df7SGuo Ren 155e9564df7SGuo Ren /* Create the ucontext. */ 156e9564df7SGuo Ren err |= __put_user(0, &frame->uc.uc_flags); 157e9564df7SGuo Ren err |= __put_user(0, &frame->uc.uc_link); 158e9564df7SGuo Ren err |= __put_user((void *)current->sas_ss_sp, 159e9564df7SGuo Ren &frame->uc.uc_stack.ss_sp); 160e9564df7SGuo Ren err |= __put_user(sas_ss_flags(regs->usp), 161e9564df7SGuo Ren &frame->uc.uc_stack.ss_flags); 162e9564df7SGuo Ren err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 163e9564df7SGuo Ren err |= setup_sigframe(&frame->uc.uc_mcontext, regs); 164e9564df7SGuo Ren err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 165e9564df7SGuo Ren 166e9564df7SGuo Ren if (err) 167e9564df7SGuo Ren goto give_sigsegv; 168e9564df7SGuo Ren 169e9564df7SGuo Ren /* Set up registers for signal handler */ 170e9564df7SGuo Ren regs->usp = (unsigned long)frame; 171e9564df7SGuo Ren regs->pc = (unsigned long)ksig->ka.sa.sa_handler; 172e9564df7SGuo Ren regs->lr = (unsigned long)vdso->rt_signal_retcode; 173e9564df7SGuo Ren 174e9564df7SGuo Ren adjust_stack: 175e9564df7SGuo Ren regs->a0 = ksig->sig; /* first arg is signo */ 176e9564df7SGuo Ren regs->a1 = (unsigned long)(&(frame->info)); 177e9564df7SGuo Ren regs->a2 = (unsigned long)(&(frame->uc)); 178e9564df7SGuo Ren return err; 179e9564df7SGuo Ren 180e9564df7SGuo Ren give_sigsegv: 181e9564df7SGuo Ren if (ksig->sig == SIGSEGV) 182e9564df7SGuo Ren ksig->ka.sa.sa_handler = SIG_DFL; 183e9564df7SGuo Ren force_sig(SIGSEGV, current); 184e9564df7SGuo Ren goto adjust_stack; 185e9564df7SGuo Ren } 186e9564df7SGuo Ren 187e9564df7SGuo Ren /* 188e9564df7SGuo Ren * OK, we're invoking a handler 189e9564df7SGuo Ren */ 190e9564df7SGuo Ren static int 191e9564df7SGuo Ren handle_signal(struct ksignal *ksig, struct pt_regs *regs) 192e9564df7SGuo Ren { 193e9564df7SGuo Ren int ret; 194e9564df7SGuo Ren sigset_t *oldset = sigmask_to_save(); 195e9564df7SGuo Ren 196e9564df7SGuo Ren /* 197e9564df7SGuo Ren * set up the stack frame, regardless of SA_SIGINFO, 198e9564df7SGuo Ren * and pass info anyway. 199e9564df7SGuo Ren */ 200e9564df7SGuo Ren ret = setup_rt_frame(ksig, oldset, regs); 201e9564df7SGuo Ren 202e9564df7SGuo Ren if (ret != 0) { 203e9564df7SGuo Ren force_sigsegv(ksig->sig, current); 204e9564df7SGuo Ren return ret; 205e9564df7SGuo Ren } 206e9564df7SGuo Ren 207e9564df7SGuo Ren /* Block the signal if we were successful. */ 208e9564df7SGuo Ren spin_lock_irq(¤t->sighand->siglock); 209e9564df7SGuo Ren sigorsets(¤t->blocked, ¤t->blocked, &ksig->ka.sa.sa_mask); 210e9564df7SGuo Ren if (!(ksig->ka.sa.sa_flags & SA_NODEFER)) 211e9564df7SGuo Ren sigaddset(¤t->blocked, ksig->sig); 212e9564df7SGuo Ren recalc_sigpending(); 213e9564df7SGuo Ren spin_unlock_irq(¤t->sighand->siglock); 214e9564df7SGuo Ren 215e9564df7SGuo Ren return 0; 216e9564df7SGuo Ren } 217e9564df7SGuo Ren 218e9564df7SGuo Ren /* 219e9564df7SGuo Ren * Note that 'init' is a special process: it doesn't get signals it doesn't 220e9564df7SGuo Ren * want to handle. Thus you cannot kill init even with a SIGKILL even by 221e9564df7SGuo Ren * mistake. 222e9564df7SGuo Ren * 223e9564df7SGuo Ren * Note that we go through the signals twice: once to check the signals 224e9564df7SGuo Ren * that the kernel can handle, and then we build all the user-level signal 225e9564df7SGuo Ren * handling stack-frames in one go after that. 226e9564df7SGuo Ren */ 227e9564df7SGuo Ren static void do_signal(struct pt_regs *regs, int syscall) 228e9564df7SGuo Ren { 229e9564df7SGuo Ren unsigned int retval = 0, continue_addr = 0, restart_addr = 0; 230e9564df7SGuo Ren struct ksignal ksig; 231e9564df7SGuo Ren 232e9564df7SGuo Ren /* 233e9564df7SGuo Ren * We want the common case to go fast, which 234e9564df7SGuo Ren * is why we may in certain cases get here from 235e9564df7SGuo Ren * kernel mode. Just return without doing anything 236e9564df7SGuo Ren * if so. 237e9564df7SGuo Ren */ 238e9564df7SGuo Ren if (!user_mode(regs)) 239e9564df7SGuo Ren return; 240e9564df7SGuo Ren 241e9564df7SGuo Ren current->thread.esp0 = (unsigned long)regs; 242e9564df7SGuo Ren 243e9564df7SGuo Ren /* 244e9564df7SGuo Ren * If we were from a system call, check for system call restarting... 245e9564df7SGuo Ren */ 246e9564df7SGuo Ren if (syscall) { 247e9564df7SGuo Ren continue_addr = regs->pc; 248e9564df7SGuo Ren #if defined(__CSKYABIV2__) 249e9564df7SGuo Ren restart_addr = continue_addr - 4; 250e9564df7SGuo Ren #else 251e9564df7SGuo Ren restart_addr = continue_addr - 2; 252e9564df7SGuo Ren #endif 253e9564df7SGuo Ren retval = regs->a0; 254e9564df7SGuo Ren 255e9564df7SGuo Ren /* 256e9564df7SGuo Ren * Prepare for system call restart. We do this here so that a 257e9564df7SGuo Ren * debugger will see the already changed. 258e9564df7SGuo Ren */ 259e9564df7SGuo Ren switch (retval) { 260e9564df7SGuo Ren case -ERESTARTNOHAND: 261e9564df7SGuo Ren case -ERESTARTSYS: 262e9564df7SGuo Ren case -ERESTARTNOINTR: 263e9564df7SGuo Ren regs->a0 = regs->orig_a0; 264e9564df7SGuo Ren regs->pc = restart_addr; 265e9564df7SGuo Ren break; 266e9564df7SGuo Ren case -ERESTART_RESTARTBLOCK: 267e9564df7SGuo Ren regs->a0 = -EINTR; 268e9564df7SGuo Ren break; 269e9564df7SGuo Ren } 270e9564df7SGuo Ren } 271e9564df7SGuo Ren 272e9564df7SGuo Ren if (try_to_freeze()) 273e9564df7SGuo Ren goto no_signal; 274e9564df7SGuo Ren 275e9564df7SGuo Ren /* 276e9564df7SGuo Ren * Get the signal to deliver. When running under ptrace, at this 277e9564df7SGuo Ren * point the debugger may change all our registers ... 278e9564df7SGuo Ren */ 279e9564df7SGuo Ren if (get_signal(&ksig)) { 280e9564df7SGuo Ren /* 281e9564df7SGuo Ren * Depending on the signal settings we may need to revert the 282e9564df7SGuo Ren * decision to restart the system call. But skip this if a 283e9564df7SGuo Ren * debugger has chosen to restart at a different PC. 284e9564df7SGuo Ren */ 285e9564df7SGuo Ren if (regs->pc == restart_addr) { 286e9564df7SGuo Ren if (retval == -ERESTARTNOHAND || 287e9564df7SGuo Ren (retval == -ERESTARTSYS && 288e9564df7SGuo Ren !(ksig.ka.sa.sa_flags & SA_RESTART))) { 289e9564df7SGuo Ren regs->a0 = -EINTR; 290e9564df7SGuo Ren regs->pc = continue_addr; 291e9564df7SGuo Ren } 292e9564df7SGuo Ren } 293e9564df7SGuo Ren 294e9564df7SGuo Ren /* Whee! Actually deliver the signal. */ 295e9564df7SGuo Ren if (handle_signal(&ksig, regs) == 0) { 296e9564df7SGuo Ren /* 297e9564df7SGuo Ren * A signal was successfully delivered; the saved 298e9564df7SGuo Ren * sigmask will have been stored in the signal frame, 299e9564df7SGuo Ren * and will be restored by sigreturn, so we can simply 300e9564df7SGuo Ren * clear the TIF_RESTORE_SIGMASK flag. 301e9564df7SGuo Ren */ 302e9564df7SGuo Ren if (test_thread_flag(TIF_RESTORE_SIGMASK)) 303e9564df7SGuo Ren clear_thread_flag(TIF_RESTORE_SIGMASK); 304e9564df7SGuo Ren } 305e9564df7SGuo Ren return; 306e9564df7SGuo Ren } 307e9564df7SGuo Ren 308e9564df7SGuo Ren no_signal: 309e9564df7SGuo Ren if (syscall) { 310e9564df7SGuo Ren /* 311e9564df7SGuo Ren * Handle restarting a different system call. As above, 312e9564df7SGuo Ren * if a debugger has chosen to restart at a different PC, 313e9564df7SGuo Ren * ignore the restart. 314e9564df7SGuo Ren */ 315e9564df7SGuo Ren if (retval == -ERESTART_RESTARTBLOCK 316e9564df7SGuo Ren && regs->pc == continue_addr) { 317e9564df7SGuo Ren #if defined(__CSKYABIV2__) 318e9564df7SGuo Ren regs->regs[3] = __NR_restart_syscall; 319e9564df7SGuo Ren regs->pc -= 4; 320e9564df7SGuo Ren #else 321e9564df7SGuo Ren regs->regs[9] = __NR_restart_syscall; 322e9564df7SGuo Ren regs->pc -= 2; 323e9564df7SGuo Ren #endif 324e9564df7SGuo Ren } 325e9564df7SGuo Ren 326e9564df7SGuo Ren /* 327e9564df7SGuo Ren * If there's no signal to deliver, we just put the saved 328e9564df7SGuo Ren * sigmask back. 329e9564df7SGuo Ren */ 330e9564df7SGuo Ren if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 331e9564df7SGuo Ren clear_thread_flag(TIF_RESTORE_SIGMASK); 332e9564df7SGuo Ren sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); 333e9564df7SGuo Ren } 334e9564df7SGuo Ren } 335e9564df7SGuo Ren } 336e9564df7SGuo Ren 337e9564df7SGuo Ren asmlinkage void 338e9564df7SGuo Ren do_notify_resume(unsigned int thread_flags, struct pt_regs *regs, int syscall) 339e9564df7SGuo Ren { 340e9564df7SGuo Ren if (thread_flags & _TIF_SIGPENDING) 341e9564df7SGuo Ren do_signal(regs, syscall); 342e9564df7SGuo Ren 343e9564df7SGuo Ren if (thread_flags & _TIF_NOTIFY_RESUME) { 344e9564df7SGuo Ren clear_thread_flag(TIF_NOTIFY_RESUME); 345e9564df7SGuo Ren tracehook_notify_resume(regs); 346e9564df7SGuo Ren } 347e9564df7SGuo Ren } 348