1/* signal.c: FRV specific bits of signal handling 2 * 3 * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * - Derived from arch/m68k/kernel/signal.c 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 10 * 2 of the License, or (at your option) any later version. 11 */ 12 13#include <linux/sched.h> 14#include <linux/mm.h> 15#include <linux/smp.h> 16#include <linux/kernel.h> 17#include <linux/signal.h> 18#include <linux/errno.h> 19#include <linux/wait.h> 20#include <linux/ptrace.h> 21#include <linux/unistd.h> 22#include <linux/personality.h> 23#include <linux/tracehook.h> 24#include <asm/ucontext.h> 25#include <asm/uaccess.h> 26#include <asm/cacheflush.h> 27 28#define DEBUG_SIG 0 29 30struct fdpic_func_descriptor { 31 unsigned long text; 32 unsigned long GOT; 33}; 34 35/* 36 * Do a signal return; undo the signal stack. 37 */ 38 39struct sigframe 40{ 41 __sigrestore_t pretcode; 42 int sig; 43 struct sigcontext sc; 44 unsigned long extramask[_NSIG_WORDS-1]; 45 uint32_t retcode[2]; 46}; 47 48struct rt_sigframe 49{ 50 __sigrestore_t pretcode; 51 int sig; 52 struct siginfo __user *pinfo; 53 void __user *puc; 54 struct siginfo info; 55 struct ucontext uc; 56 uint32_t retcode[2]; 57}; 58 59static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8) 60{ 61 struct user_context *user = current->thread.user; 62 unsigned long tbr, psr; 63 64 /* Always make any pending restarted system calls return -EINTR */ 65 current->restart_block.fn = do_no_restart_syscall; 66 67 tbr = user->i.tbr; 68 psr = user->i.psr; 69 if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context))) 70 goto badframe; 71 user->i.tbr = tbr; 72 user->i.psr = psr; 73 74 restore_user_regs(user); 75 76 user->i.syscallno = -1; /* disable syscall checks */ 77 78 *_gr8 = user->i.gr[8]; 79 return 0; 80 81 badframe: 82 return 1; 83} 84 85asmlinkage int sys_sigreturn(void) 86{ 87 struct sigframe __user *frame = (struct sigframe __user *) __frame->sp; 88 sigset_t set; 89 int gr8; 90 91 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 92 goto badframe; 93 if (__get_user(set.sig[0], &frame->sc.sc_oldmask)) 94 goto badframe; 95 96 if (_NSIG_WORDS > 1 && 97 __copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask))) 98 goto badframe; 99 100 set_current_blocked(&set); 101 102 if (restore_sigcontext(&frame->sc, &gr8)) 103 goto badframe; 104 return gr8; 105 106 badframe: 107 force_sig(SIGSEGV, current); 108 return 0; 109} 110 111asmlinkage int sys_rt_sigreturn(void) 112{ 113 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) __frame->sp; 114 sigset_t set; 115 int gr8; 116 117 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 118 goto badframe; 119 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 120 goto badframe; 121 122 set_current_blocked(&set); 123 124 if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8)) 125 goto badframe; 126 127 if (restore_altstack(&frame->uc.uc_stack)) 128 goto badframe; 129 130 return gr8; 131 132badframe: 133 force_sig(SIGSEGV, current); 134 return 0; 135} 136 137/* 138 * Set up a signal frame 139 */ 140static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask) 141{ 142 save_user_regs(current->thread.user); 143 144 if (copy_to_user(&sc->sc_context, current->thread.user, sizeof(sc->sc_context)) != 0) 145 goto badframe; 146 147 /* non-iBCS2 extensions.. */ 148 if (__put_user(mask, &sc->sc_oldmask) < 0) 149 goto badframe; 150 151 return 0; 152 153 badframe: 154 return 1; 155} 156 157/*****************************************************************************/ 158/* 159 * Determine which stack to use.. 160 */ 161static inline void __user *get_sigframe(struct ksignal *ksig, 162 size_t frame_size) 163{ 164 unsigned long sp = sigsp(__frame->sp, ksig); 165 166 return (void __user *) ((sp - frame_size) & ~7UL); 167 168} /* end get_sigframe() */ 169 170/*****************************************************************************/ 171/* 172 * 173 */ 174static int setup_frame(struct ksignal *ksig, sigset_t *set) 175{ 176 struct sigframe __user *frame; 177 int sig = ksig->sig; 178 179 frame = get_sigframe(ksig, sizeof(*frame)); 180 181 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 182 return -EFAULT; 183 184 if (__put_user(sig, &frame->sig) < 0) 185 return -EFAULT; 186 187 if (setup_sigcontext(&frame->sc, set->sig[0])) 188 return -EFAULT; 189 190 if (_NSIG_WORDS > 1) { 191 if (__copy_to_user(frame->extramask, &set->sig[1], 192 sizeof(frame->extramask))) 193 return -EFAULT; 194 } 195 196 /* Set up to return from userspace. If provided, use a stub 197 * already in userspace. */ 198 if (ksig->ka.sa.sa_flags & SA_RESTORER) { 199 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode) < 0) 200 return -EFAULT; 201 } 202 else { 203 /* Set up the following code on the stack: 204 * setlos #__NR_sigreturn,gr7 205 * tira gr0,0 206 */ 207 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || 208 __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) || 209 __put_user(0xc0700000, &frame->retcode[1])) 210 return -EFAULT; 211 212 flush_icache_range((unsigned long) frame->retcode, 213 (unsigned long) (frame->retcode + 2)); 214 } 215 216 /* Set up registers for the signal handler */ 217 if (current->personality & FDPIC_FUNCPTRS) { 218 struct fdpic_func_descriptor __user *funcptr = 219 (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler; 220 struct fdpic_func_descriptor desc; 221 if (copy_from_user(&desc, funcptr, sizeof(desc))) 222 return -EFAULT; 223 __frame->pc = desc.text; 224 __frame->gr15 = desc.GOT; 225 } else { 226 __frame->pc = (unsigned long) ksig->ka.sa.sa_handler; 227 __frame->gr15 = 0; 228 } 229 230 __frame->sp = (unsigned long) frame; 231 __frame->lr = (unsigned long) &frame->retcode; 232 __frame->gr8 = sig; 233 234#if DEBUG_SIG 235 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 236 sig, current->comm, current->pid, frame, __frame->pc, 237 frame->pretcode); 238#endif 239 240 return 0; 241} /* end setup_frame() */ 242 243/*****************************************************************************/ 244/* 245 * 246 */ 247static int setup_rt_frame(struct ksignal *ksig, sigset_t *set) 248{ 249 struct rt_sigframe __user *frame; 250 int sig = ksig->sig; 251 252 frame = get_sigframe(ksig, sizeof(*frame)); 253 254 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 255 return -EFAULT; 256 257 if (__put_user(sig, &frame->sig) || 258 __put_user(&frame->info, &frame->pinfo) || 259 __put_user(&frame->uc, &frame->puc)) 260 return -EFAULT; 261 262 if (copy_siginfo_to_user(&frame->info, &ksig->info)) 263 return -EFAULT; 264 265 /* Create the ucontext. */ 266 if (__put_user(0, &frame->uc.uc_flags) || 267 __put_user(NULL, &frame->uc.uc_link) || 268 __save_altstack(&frame->uc.uc_stack, __frame->sp)) 269 return -EFAULT; 270 271 if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0])) 272 return -EFAULT; 273 274 if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) 275 return -EFAULT; 276 277 /* Set up to return from userspace. If provided, use a stub 278 * already in userspace. */ 279 if (ksig->ka.sa.sa_flags & SA_RESTORER) { 280 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode)) 281 return -EFAULT; 282 } 283 else { 284 /* Set up the following code on the stack: 285 * setlos #__NR_sigreturn,gr7 286 * tira gr0,0 287 */ 288 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || 289 __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) || 290 __put_user(0xc0700000, &frame->retcode[1])) 291 return -EFAULT; 292 293 flush_icache_range((unsigned long) frame->retcode, 294 (unsigned long) (frame->retcode + 2)); 295 } 296 297 /* Set up registers for signal handler */ 298 if (current->personality & FDPIC_FUNCPTRS) { 299 struct fdpic_func_descriptor __user *funcptr = 300 (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler; 301 struct fdpic_func_descriptor desc; 302 if (copy_from_user(&desc, funcptr, sizeof(desc))) 303 return -EFAULT; 304 __frame->pc = desc.text; 305 __frame->gr15 = desc.GOT; 306 } else { 307 __frame->pc = (unsigned long) ksig->ka.sa.sa_handler; 308 __frame->gr15 = 0; 309 } 310 311 __frame->sp = (unsigned long) frame; 312 __frame->lr = (unsigned long) &frame->retcode; 313 __frame->gr8 = sig; 314 __frame->gr9 = (unsigned long) &frame->info; 315 316#if DEBUG_SIG 317 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 318 sig, current->comm, current->pid, frame, __frame->pc, 319 frame->pretcode); 320#endif 321 return 0; 322 323} /* end setup_rt_frame() */ 324 325/*****************************************************************************/ 326/* 327 * OK, we're invoking a handler 328 */ 329static void handle_signal(struct ksignal *ksig) 330{ 331 sigset_t *oldset = sigmask_to_save(); 332 int ret; 333 334 /* Are we from a system call? */ 335 if (__frame->syscallno != -1) { 336 /* If so, check system call restarting.. */ 337 switch (__frame->gr8) { 338 case -ERESTART_RESTARTBLOCK: 339 case -ERESTARTNOHAND: 340 __frame->gr8 = -EINTR; 341 break; 342 343 case -ERESTARTSYS: 344 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { 345 __frame->gr8 = -EINTR; 346 break; 347 } 348 349 /* fallthrough */ 350 case -ERESTARTNOINTR: 351 __frame->gr8 = __frame->orig_gr8; 352 __frame->pc -= 4; 353 } 354 __frame->syscallno = -1; 355 } 356 357 /* Set up the stack frame */ 358 if (ksig->ka.sa.sa_flags & SA_SIGINFO) 359 ret = setup_rt_frame(ksig, oldset); 360 else 361 ret = setup_frame(ksig, oldset); 362 363 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); 364} /* end handle_signal() */ 365 366/*****************************************************************************/ 367/* 368 * Note that 'init' is a special process: it doesn't get signals it doesn't 369 * want to handle. Thus you cannot kill init even with a SIGKILL even by 370 * mistake. 371 */ 372static void do_signal(void) 373{ 374 struct ksignal ksig; 375 376 if (get_signal(&ksig)) { 377 handle_signal(&ksig); 378 return; 379 } 380 381 /* Did we come from a system call? */ 382 if (__frame->syscallno != -1) { 383 /* Restart the system call - no handlers present */ 384 switch (__frame->gr8) { 385 case -ERESTARTNOHAND: 386 case -ERESTARTSYS: 387 case -ERESTARTNOINTR: 388 __frame->gr8 = __frame->orig_gr8; 389 __frame->pc -= 4; 390 break; 391 392 case -ERESTART_RESTARTBLOCK: 393 __frame->gr7 = __NR_restart_syscall; 394 __frame->pc -= 4; 395 break; 396 } 397 __frame->syscallno = -1; 398 } 399 400 /* if there's no signal to deliver, we just put the saved sigmask 401 * back */ 402 restore_saved_sigmask(); 403} /* end do_signal() */ 404 405/*****************************************************************************/ 406/* 407 * notification of userspace execution resumption 408 * - triggered by the TIF_WORK_MASK flags 409 */ 410asmlinkage void do_notify_resume(__u32 thread_info_flags) 411{ 412 /* pending single-step? */ 413 if (thread_info_flags & _TIF_SINGLESTEP) 414 clear_thread_flag(TIF_SINGLESTEP); 415 416 /* deal with pending signal delivery */ 417 if (thread_info_flags & _TIF_SIGPENDING) 418 do_signal(); 419 420 /* deal with notification on about to resume userspace execution */ 421 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 422 clear_thread_flag(TIF_NOTIFY_RESUME); 423 tracehook_notify_resume(__frame); 424 } 425 426} /* end do_notify_resume() */ 427