1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * OpenRISC signal.c 4 * 5 * Linux architectural port borrowing liberally from similar works of 6 * others. All original copyrights apply as per the original source 7 * declaration. 8 * 9 * Modifications for the OpenRISC architecture: 10 * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> 11 * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> 12 */ 13 14 #include <linux/sched.h> 15 #include <linux/mm.h> 16 #include <linux/smp.h> 17 #include <linux/kernel.h> 18 #include <linux/signal.h> 19 #include <linux/errno.h> 20 #include <linux/wait.h> 21 #include <linux/ptrace.h> 22 #include <linux/unistd.h> 23 #include <linux/stddef.h> 24 #include <linux/tracehook.h> 25 26 #include <asm/processor.h> 27 #include <asm/syscall.h> 28 #include <asm/ucontext.h> 29 #include <linux/uaccess.h> 30 31 struct rt_sigframe { 32 struct siginfo info; 33 struct ucontext uc; 34 unsigned char retcode[16]; /* trampoline code */ 35 }; 36 37 static int restore_sigcontext(struct pt_regs *regs, 38 struct sigcontext __user *sc) 39 { 40 int err = 0; 41 42 /* Always make any pending restarted system calls return -EINTR */ 43 current->restart_block.fn = do_no_restart_syscall; 44 45 /* 46 * Restore the regs from &sc->regs. 47 * (sc is already checked since the sigframe was 48 * checked in sys_sigreturn previously) 49 */ 50 err |= __copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long)); 51 err |= __copy_from_user(®s->pc, &sc->regs.pc, sizeof(unsigned long)); 52 err |= __copy_from_user(®s->sr, &sc->regs.sr, sizeof(unsigned long)); 53 54 /* make sure the SM-bit is cleared so user-mode cannot fool us */ 55 regs->sr &= ~SPR_SR_SM; 56 57 regs->orig_gpr11 = -1; /* Avoid syscall restart checks */ 58 59 /* TODO: the other ports use regs->orig_XX to disable syscall checks 60 * after this completes, but we don't use that mechanism. maybe we can 61 * use it now ? 62 */ 63 64 return err; 65 } 66 67 asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) 68 { 69 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->sp; 70 sigset_t set; 71 72 /* 73 * Since we stacked the signal on a dword boundary, 74 * then frame should be dword aligned here. If it's 75 * not, then the user is trying to mess with us. 76 */ 77 if (((unsigned long)frame) & 3) 78 goto badframe; 79 80 if (!access_ok(frame, sizeof(*frame))) 81 goto badframe; 82 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 83 goto badframe; 84 85 set_current_blocked(&set); 86 87 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 88 goto badframe; 89 90 if (restore_altstack(&frame->uc.uc_stack)) 91 goto badframe; 92 93 return regs->gpr[11]; 94 95 badframe: 96 force_sig(SIGSEGV); 97 return 0; 98 } 99 100 /* 101 * Set up a signal frame. 102 */ 103 104 static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 105 { 106 int err = 0; 107 108 /* copy the regs */ 109 /* There should be no need to save callee-saved registers here... 110 * ...but we save them anyway. Revisit this 111 */ 112 err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long)); 113 err |= __copy_to_user(&sc->regs.pc, ®s->pc, sizeof(unsigned long)); 114 err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long)); 115 116 return err; 117 } 118 119 static inline unsigned long align_sigframe(unsigned long sp) 120 { 121 return sp & ~3UL; 122 } 123 124 /* 125 * Work out where the signal frame should go. It's either on the user stack 126 * or the alternate stack. 127 */ 128 129 static inline void __user *get_sigframe(struct ksignal *ksig, 130 struct pt_regs *regs, size_t frame_size) 131 { 132 unsigned long sp = regs->sp; 133 134 /* redzone */ 135 sp -= STACK_FRAME_OVERHEAD; 136 sp = sigsp(sp, ksig); 137 sp = align_sigframe(sp - frame_size); 138 139 return (void __user *)sp; 140 } 141 142 /* grab and setup a signal frame. 143 * 144 * basically we stack a lot of state info, and arrange for the 145 * user-mode program to return to the kernel using either a 146 * trampoline which performs the syscall sigreturn, or a provided 147 * user-mode trampoline. 148 */ 149 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, 150 struct pt_regs *regs) 151 { 152 struct rt_sigframe __user *frame; 153 unsigned long return_ip; 154 int err = 0; 155 156 frame = get_sigframe(ksig, regs, sizeof(*frame)); 157 158 if (!access_ok(frame, sizeof(*frame))) 159 return -EFAULT; 160 161 /* Create siginfo. */ 162 if (ksig->ka.sa.sa_flags & SA_SIGINFO) 163 err |= copy_siginfo_to_user(&frame->info, &ksig->info); 164 165 /* Create the ucontext. */ 166 err |= __put_user(0, &frame->uc.uc_flags); 167 err |= __put_user(NULL, &frame->uc.uc_link); 168 err |= __save_altstack(&frame->uc.uc_stack, regs->sp); 169 err |= setup_sigcontext(regs, &frame->uc.uc_mcontext); 170 171 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 172 173 if (err) 174 return -EFAULT; 175 176 /* trampoline - the desired return ip is the retcode itself */ 177 return_ip = (unsigned long)&frame->retcode; 178 /* This is: 179 l.ori r11,r0,__NR_sigreturn 180 l.sys 1 181 */ 182 err |= __put_user(0xa960, (short __user *)(frame->retcode + 0)); 183 err |= __put_user(__NR_rt_sigreturn, (short __user *)(frame->retcode + 2)); 184 err |= __put_user(0x20000001, (unsigned long __user *)(frame->retcode + 4)); 185 err |= __put_user(0x15000000, (unsigned long __user *)(frame->retcode + 8)); 186 187 if (err) 188 return -EFAULT; 189 190 /* Set up registers for signal handler */ 191 regs->pc = (unsigned long)ksig->ka.sa.sa_handler; /* what we enter NOW */ 192 regs->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */ 193 regs->gpr[3] = (unsigned long)ksig->sig; /* arg 1: signo */ 194 regs->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */ 195 regs->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */ 196 197 /* actually move the usp to reflect the stacked frame */ 198 regs->sp = (unsigned long)frame; 199 200 return 0; 201 } 202 203 static inline void 204 handle_signal(struct ksignal *ksig, struct pt_regs *regs) 205 { 206 int ret; 207 208 ret = setup_rt_frame(ksig, sigmask_to_save(), regs); 209 210 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); 211 } 212 213 /* 214 * Note that 'init' is a special process: it doesn't get signals it doesn't 215 * want to handle. Thus you cannot kill init even with a SIGKILL even by 216 * mistake. 217 * 218 * Also note that the regs structure given here as an argument, is the latest 219 * pushed pt_regs. It may or may not be the same as the first pushed registers 220 * when the initial usermode->kernelmode transition took place. Therefore 221 * we can use user_mode(regs) to see if we came directly from kernel or user 222 * mode below. 223 */ 224 225 int do_signal(struct pt_regs *regs, int syscall) 226 { 227 struct ksignal ksig; 228 unsigned long continue_addr = 0; 229 unsigned long restart_addr = 0; 230 unsigned long retval = 0; 231 int restart = 0; 232 233 if (syscall) { 234 continue_addr = regs->pc; 235 restart_addr = continue_addr - 4; 236 retval = regs->gpr[11]; 237 238 /* 239 * Setup syscall restart here so that a debugger will 240 * see the already changed PC. 241 */ 242 switch (retval) { 243 case -ERESTART_RESTARTBLOCK: 244 restart = -2; 245 fallthrough; 246 case -ERESTARTNOHAND: 247 case -ERESTARTSYS: 248 case -ERESTARTNOINTR: 249 restart++; 250 regs->gpr[11] = regs->orig_gpr11; 251 regs->pc = restart_addr; 252 break; 253 } 254 } 255 256 /* 257 * Get the signal to deliver. During the call to get_signal the 258 * debugger may change all our registers so we may need to revert 259 * the decision to restart the syscall; specifically, if the PC is 260 * changed, don't restart the syscall. 261 */ 262 if (get_signal(&ksig)) { 263 if (unlikely(restart) && regs->pc == restart_addr) { 264 if (retval == -ERESTARTNOHAND || 265 retval == -ERESTART_RESTARTBLOCK 266 || (retval == -ERESTARTSYS 267 && !(ksig.ka.sa.sa_flags & SA_RESTART))) { 268 /* No automatic restart */ 269 regs->gpr[11] = -EINTR; 270 regs->pc = continue_addr; 271 } 272 } 273 handle_signal(&ksig, regs); 274 } else { 275 /* no handler */ 276 restore_saved_sigmask(); 277 /* 278 * Restore pt_regs PC as syscall restart will be handled by 279 * kernel without return to userspace 280 */ 281 if (unlikely(restart) && regs->pc == restart_addr) { 282 regs->pc = continue_addr; 283 return restart; 284 } 285 } 286 287 return 0; 288 } 289 290 asmlinkage int 291 do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) 292 { 293 do { 294 if (likely(thread_flags & _TIF_NEED_RESCHED)) { 295 schedule(); 296 } else { 297 if (unlikely(!user_mode(regs))) 298 return 0; 299 local_irq_enable(); 300 if (thread_flags & (_TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL)) { 301 int restart = do_signal(regs, syscall); 302 if (unlikely(restart)) { 303 /* 304 * Restart without handlers. 305 * Deal with it without leaving 306 * the kernel space. 307 */ 308 return restart; 309 } 310 syscall = 0; 311 } else { 312 tracehook_notify_resume(regs); 313 } 314 } 315 local_irq_disable(); 316 thread_flags = current_thread_info()->flags; 317 } while (thread_flags & _TIF_WORK_MASK); 318 return 0; 319 } 320