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