/arch/mn10300/kernel/signal.c
C | 574 lines | 406 code | 88 blank | 80 comment | 62 complexity | 7d52e8574853267c128e95d22aa420b3 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1/* MN10300 Signal handling 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11 12#include <linux/sched.h> 13#include <linux/mm.h> 14#include <linux/smp.h> 15#include <linux/kernel.h> 16#include <linux/signal.h> 17#include <linux/errno.h> 18#include <linux/wait.h> 19#include <linux/ptrace.h> 20#include <linux/unistd.h> 21#include <linux/stddef.h> 22#include <linux/tty.h> 23#include <linux/personality.h> 24#include <linux/suspend.h> 25#include <linux/tracehook.h> 26#include <asm/cacheflush.h> 27#include <asm/ucontext.h> 28#include <asm/uaccess.h> 29#include <asm/fpu.h> 30#include "sigframe.h" 31 32#define DEBUG_SIG 0 33 34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 35 36/* 37 * atomically swap in the new signal mask, and wait for a signal. 38 */ 39asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask) 40{ 41 mask &= _BLOCKABLE; 42 spin_lock_irq(¤t->sighand->siglock); 43 current->saved_sigmask = current->blocked; 44 siginitset(¤t->blocked, mask); 45 recalc_sigpending(); 46 spin_unlock_irq(¤t->sighand->siglock); 47 48 current->state = TASK_INTERRUPTIBLE; 49 schedule(); 50 set_thread_flag(TIF_RESTORE_SIGMASK); 51 return -ERESTARTNOHAND; 52} 53 54/* 55 * set signal action syscall 56 */ 57asmlinkage long sys_sigaction(int sig, 58 const struct old_sigaction __user *act, 59 struct old_sigaction __user *oact) 60{ 61 struct k_sigaction new_ka, old_ka; 62 int ret; 63 64 if (act) { 65 old_sigset_t mask; 66 if (verify_area(VERIFY_READ, act, sizeof(*act)) || 67 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 68 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 69 return -EFAULT; 70 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 71 __get_user(mask, &act->sa_mask); 72 siginitset(&new_ka.sa.sa_mask, mask); 73 } 74 75 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 76 77 if (!ret && oact) { 78 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || 79 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 80 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 81 return -EFAULT; 82 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 83 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 84 } 85 86 return ret; 87} 88 89/* 90 * set alternate signal stack syscall 91 */ 92asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t *uoss) 93{ 94 return do_sigaltstack(uss, uoss, __frame->sp); 95} 96 97/* 98 * do a signal return; undo the signal stack. 99 */ 100static int restore_sigcontext(struct pt_regs *regs, 101 struct sigcontext __user *sc, long *_d0) 102{ 103 unsigned int err = 0; 104 105 if (is_using_fpu(current)) 106 fpu_kill_state(current); 107 108#define COPY(x) err |= __get_user(regs->x, &sc->x) 109 COPY(d1); COPY(d2); COPY(d3); 110 COPY(a0); COPY(a1); COPY(a2); COPY(a3); 111 COPY(e0); COPY(e1); COPY(e2); COPY(e3); 112 COPY(e4); COPY(e5); COPY(e6); COPY(e7); 113 COPY(lar); COPY(lir); 114 COPY(mdr); COPY(mdrq); 115 COPY(mcvf); COPY(mcrl); COPY(mcrh); 116 COPY(sp); COPY(pc); 117#undef COPY 118 119 { 120 unsigned int tmpflags; 121#ifndef CONFIG_MN10300_USING_JTAG 122#define USER_EPSW (EPSW_FLAG_Z | EPSW_FLAG_N | EPSW_FLAG_C | EPSW_FLAG_V | \ 123 EPSW_T | EPSW_nAR) 124#else 125#define USER_EPSW (EPSW_FLAG_Z | EPSW_FLAG_N | EPSW_FLAG_C | EPSW_FLAG_V | \ 126 EPSW_nAR) 127#endif 128 err |= __get_user(tmpflags, &sc->epsw); 129 regs->epsw = (regs->epsw & ~USER_EPSW) | 130 (tmpflags & USER_EPSW); 131 regs->orig_d0 = -1; /* disable syscall checks */ 132 } 133 134 { 135 struct fpucontext *buf; 136 err |= __get_user(buf, &sc->fpucontext); 137 if (buf) { 138 if (verify_area(VERIFY_READ, buf, sizeof(*buf))) 139 goto badframe; 140 err |= fpu_restore_sigcontext(buf); 141 } 142 } 143 144 err |= __get_user(*_d0, &sc->d0); 145 return err; 146 147badframe: 148 return 1; 149} 150 151/* 152 * standard signal return syscall 153 */ 154asmlinkage long sys_sigreturn(void) 155{ 156 struct sigframe __user *frame = (struct sigframe __user *) __frame->sp; 157 sigset_t set; 158 long d0; 159 160 if (verify_area(VERIFY_READ, frame, sizeof(*frame))) 161 goto badframe; 162 if (__get_user(set.sig[0], &frame->sc.oldmask)) 163 goto badframe; 164 165 if (_NSIG_WORDS > 1 && 166 __copy_from_user(&set.sig[1], &frame->extramask, 167 sizeof(frame->extramask))) 168 goto badframe; 169 170 sigdelsetmask(&set, ~_BLOCKABLE); 171 spin_lock_irq(¤t->sighand->siglock); 172 current->blocked = set; 173 recalc_sigpending(); 174 spin_unlock_irq(¤t->sighand->siglock); 175 176 if (restore_sigcontext(__frame, &frame->sc, &d0)) 177 goto badframe; 178 179 return d0; 180 181badframe: 182 force_sig(SIGSEGV, current); 183 return 0; 184} 185 186/* 187 * realtime signal return syscall 188 */ 189asmlinkage long sys_rt_sigreturn(void) 190{ 191 struct rt_sigframe __user *frame = 192 (struct rt_sigframe __user *) __frame->sp; 193 sigset_t set; 194 unsigned long d0; 195 196 if (verify_area(VERIFY_READ, frame, sizeof(*frame))) 197 goto badframe; 198 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 199 goto badframe; 200 201 sigdelsetmask(&set, ~_BLOCKABLE); 202 spin_lock_irq(¤t->sighand->siglock); 203 current->blocked = set; 204 recalc_sigpending(); 205 spin_unlock_irq(¤t->sighand->siglock); 206 207 if (restore_sigcontext(__frame, &frame->uc.uc_mcontext, &d0)) 208 goto badframe; 209 210 if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT) 211 goto badframe; 212 213 return d0; 214 215badframe: 216 force_sig(SIGSEGV, current); 217 return 0; 218} 219 220/* 221 * store the userspace context into a signal frame 222 */ 223static int setup_sigcontext(struct sigcontext __user *sc, 224 struct fpucontext *fpuctx, 225 struct pt_regs *regs, 226 unsigned long mask) 227{ 228 int tmp, err = 0; 229 230#define COPY(x) err |= __put_user(regs->x, &sc->x) 231 COPY(d0); COPY(d1); COPY(d2); COPY(d3); 232 COPY(a0); COPY(a1); COPY(a2); COPY(a3); 233 COPY(e0); COPY(e1); COPY(e2); COPY(e3); 234 COPY(e4); COPY(e5); COPY(e6); COPY(e7); 235 COPY(lar); COPY(lir); 236 COPY(mdr); COPY(mdrq); 237 COPY(mcvf); COPY(mcrl); COPY(mcrh); 238 COPY(sp); COPY(epsw); COPY(pc); 239#undef COPY 240 241 tmp = fpu_setup_sigcontext(fpuctx); 242 if (tmp < 0) 243 err = 1; 244 else 245 err |= __put_user(tmp ? fpuctx : NULL, &sc->fpucontext); 246 247 /* non-iBCS2 extensions.. */ 248 err |= __put_user(mask, &sc->oldmask); 249 250 return err; 251} 252 253/* 254 * determine which stack to use.. 255 */ 256static inline void __user *get_sigframe(struct k_sigaction *ka, 257 struct pt_regs *regs, 258 size_t frame_size) 259{ 260 unsigned long sp; 261 262 /* default to using normal stack */ 263 sp = regs->sp; 264 265 /* this is the X/Open sanctioned signal stack switching. */ 266 if (ka->sa.sa_flags & SA_ONSTACK) { 267 if (sas_ss_flags(sp) == 0) 268 sp = current->sas_ss_sp + current->sas_ss_size; 269 } 270 271 return (void __user *) ((sp - frame_size) & ~7UL); 272} 273 274/* 275 * set up a normal signal frame 276 */ 277static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 278 struct pt_regs *regs) 279{ 280 struct sigframe __user *frame; 281 int rsig; 282 283 frame = get_sigframe(ka, regs, sizeof(*frame)); 284 285 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 286 goto give_sigsegv; 287 288 rsig = sig; 289 if (sig < 32 && 290 current_thread_info()->exec_domain && 291 current_thread_info()->exec_domain->signal_invmap) 292 rsig = current_thread_info()->exec_domain->signal_invmap[sig]; 293 294 if (__put_user(rsig, &frame->sig) < 0 || 295 __put_user(&frame->sc, &frame->psc) < 0) 296 goto give_sigsegv; 297 298 if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0])) 299 goto give_sigsegv; 300 301 if (_NSIG_WORDS > 1) { 302 if (__copy_to_user(frame->extramask, &set->sig[1], 303 sizeof(frame->extramask))) 304 goto give_sigsegv; 305 } 306 307 /* set up to return from userspace. If provided, use a stub already in 308 * userspace */ 309 if (ka->sa.sa_flags & SA_RESTORER) { 310 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 311 goto give_sigsegv; 312 } else { 313 if (__put_user((void (*)(void))frame->retcode, 314 &frame->pretcode)) 315 goto give_sigsegv; 316 /* this is mov $,d0; syscall 0 */ 317 if (__put_user(0x2c, (char *)(frame->retcode + 0)) || 318 __put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) || 319 __put_user(0x00, (char *)(frame->retcode + 2)) || 320 __put_user(0xf0, (char *)(frame->retcode + 3)) || 321 __put_user(0xe0, (char *)(frame->retcode + 4))) 322 goto give_sigsegv; 323 flush_icache_range((unsigned long) frame->retcode, 324 (unsigned long) frame->retcode + 5); 325 } 326 327 /* set up registers for signal handler */ 328 regs->sp = (unsigned long) frame; 329 regs->pc = (unsigned long) ka->sa.sa_handler; 330 regs->d0 = sig; 331 regs->d1 = (unsigned long) &frame->sc; 332 333 set_fs(USER_DS); 334 335 /* the tracer may want to single-step inside the handler */ 336 if (test_thread_flag(TIF_SINGLESTEP)) 337 ptrace_notify(SIGTRAP); 338 339#if DEBUG_SIG 340 printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 341 sig, current->comm, current->pid, frame, regs->pc, 342 frame->pretcode); 343#endif 344 345 return 0; 346 347give_sigsegv: 348 force_sig(SIGSEGV, current); 349 return -EFAULT; 350} 351 352/* 353 * set up a realtime signal frame 354 */ 355static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 356 sigset_t *set, struct pt_regs *regs) 357{ 358 struct rt_sigframe __user *frame; 359 int rsig; 360 361 frame = get_sigframe(ka, regs, sizeof(*frame)); 362 363 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 364 goto give_sigsegv; 365 366 rsig = sig; 367 if (sig < 32 && 368 current_thread_info()->exec_domain && 369 current_thread_info()->exec_domain->signal_invmap) 370 rsig = current_thread_info()->exec_domain->signal_invmap[sig]; 371 372 if (__put_user(rsig, &frame->sig) || 373 __put_user(&frame->info, &frame->pinfo) || 374 __put_user(&frame->uc, &frame->puc) || 375 copy_siginfo_to_user(&frame->info, info)) 376 goto give_sigsegv; 377 378 /* create the ucontext. */ 379 if (__put_user(0, &frame->uc.uc_flags) || 380 __put_user(0, &frame->uc.uc_link) || 381 __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || 382 __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) || 383 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size) || 384 setup_sigcontext(&frame->uc.uc_mcontext, 385 &frame->fpuctx, regs, set->sig[0]) || 386 __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) 387 goto give_sigsegv; 388 389 /* set up to return from userspace. If provided, use a stub already in 390 * userspace */ 391 if (ka->sa.sa_flags & SA_RESTORER) { 392 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 393 goto give_sigsegv; 394 } else { 395 if (__put_user((void(*)(void))frame->retcode, 396 &frame->pretcode) || 397 /* This is mov $,d0; syscall 0 */ 398 __put_user(0x2c, (char *)(frame->retcode + 0)) || 399 __put_user(__NR_rt_sigreturn, 400 (char *)(frame->retcode + 1)) || 401 __put_user(0x00, (char *)(frame->retcode + 2)) || 402 __put_user(0xf0, (char *)(frame->retcode + 3)) || 403 __put_user(0xe0, (char *)(frame->retcode + 4))) 404 goto give_sigsegv; 405 406 flush_icache_range((u_long) frame->retcode, 407 (u_long) frame->retcode + 5); 408 } 409 410 /* Set up registers for signal handler */ 411 regs->sp = (unsigned long) frame; 412 regs->pc = (unsigned long) ka->sa.sa_handler; 413 regs->d0 = sig; 414 regs->d1 = (long) &frame->info; 415 416 set_fs(USER_DS); 417 418 /* the tracer may want to single-step inside the handler */ 419 if (test_thread_flag(TIF_SINGLESTEP)) 420 ptrace_notify(SIGTRAP); 421 422#if DEBUG_SIG 423 printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 424 sig, current->comm, current->pid, frame, regs->pc, 425 frame->pretcode); 426#endif 427 428 return 0; 429 430give_sigsegv: 431 force_sig(SIGSEGV, current); 432 return -EFAULT; 433} 434 435/* 436 * handle the actual delivery of a signal to userspace 437 */ 438static int handle_signal(int sig, 439 siginfo_t *info, struct k_sigaction *ka, 440 sigset_t *oldset, struct pt_regs *regs) 441{ 442 int ret; 443 444 /* Are we from a system call? */ 445 if (regs->orig_d0 >= 0) { 446 /* If so, check system call restarting.. */ 447 switch (regs->d0) { 448 case -ERESTART_RESTARTBLOCK: 449 case -ERESTARTNOHAND: 450 regs->d0 = -EINTR; 451 break; 452 453 case -ERESTARTSYS: 454 if (!(ka->sa.sa_flags & SA_RESTART)) { 455 regs->d0 = -EINTR; 456 break; 457 } 458 459 /* fallthrough */ 460 case -ERESTARTNOINTR: 461 regs->d0 = regs->orig_d0; 462 regs->pc -= 2; 463 } 464 } 465 466 /* Set up the stack frame */ 467 if (ka->sa.sa_flags & SA_SIGINFO) 468 ret = setup_rt_frame(sig, ka, info, oldset, regs); 469 else 470 ret = setup_frame(sig, ka, oldset, regs); 471 472 if (ret == 0) { 473 spin_lock_irq(¤t->sighand->siglock); 474 sigorsets(¤t->blocked, ¤t->blocked, 475 &ka->sa.sa_mask); 476 if (!(ka->sa.sa_flags & SA_NODEFER)) 477 sigaddset(¤t->blocked, sig); 478 recalc_sigpending(); 479 spin_unlock_irq(¤t->sighand->siglock); 480 } 481 482 return ret; 483} 484 485/* 486 * handle a potential signal 487 */ 488static void do_signal(struct pt_regs *regs) 489{ 490 struct k_sigaction ka; 491 siginfo_t info; 492 sigset_t *oldset; 493 int signr; 494 495 /* we want the common case to go fast, which is why we may in certain 496 * cases get here from kernel mode */ 497 if (!user_mode(regs)) 498 return; 499 500 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 501 oldset = ¤t->saved_sigmask; 502 else 503 oldset = ¤t->blocked; 504 505 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 506 if (signr > 0) { 507 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 508 /* a signal was successfully delivered; the saved 509 * sigmask will have been stored in the signal frame, 510 * and will be restored by sigreturn, so we can simply 511 * clear the TIF_RESTORE_SIGMASK flag */ 512 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 513 clear_thread_flag(TIF_RESTORE_SIGMASK); 514 515 tracehook_signal_handler(signr, &info, &ka, regs, 516 test_thread_flag(TIF_SINGLESTEP)); 517 } 518 519 return; 520 } 521 522 /* did we come from a system call? */ 523 if (regs->orig_d0 >= 0) { 524 /* restart the system call - no handlers present */ 525 switch (regs->d0) { 526 case -ERESTARTNOHAND: 527 case -ERESTARTSYS: 528 case -ERESTARTNOINTR: 529 regs->d0 = regs->orig_d0; 530 regs->pc -= 2; 531 break; 532 533 case -ERESTART_RESTARTBLOCK: 534 regs->d0 = __NR_restart_syscall; 535 regs->pc -= 2; 536 break; 537 } 538 } 539 540 /* if there's no signal to deliver, we just put the saved sigmask 541 * back */ 542 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 543 clear_thread_flag(TIF_RESTORE_SIGMASK); 544 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); 545 } 546} 547 548/* 549 * notification of userspace execution resumption 550 * - triggered by current->work.notify_resume 551 */ 552asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) 553{ 554 /* Pending single-step? */ 555 if (thread_info_flags & _TIF_SINGLESTEP) { 556#ifndef CONFIG_MN10300_USING_JTAG 557 regs->epsw |= EPSW_T; 558 clear_thread_flag(TIF_SINGLESTEP); 559#else 560 BUG(); /* no h/w single-step if using JTAG unit */ 561#endif 562 } 563 564 /* deal with pending signal delivery */ 565 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 566 do_signal(regs); 567 568 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 569 clear_thread_flag(TIF_NOTIFY_RESUME); 570 tracehook_notify_resume(__frame); 571 if (current->replacement_session_keyring) 572 key_replace_session_keyring(); 573 } 574}