1/* 2 * linux/arch/h8300/kernel/signal.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive 8 * for more details. 9 */ 10 11/* 12 * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp> 13 * and David McCullough <davidm@snapgear.com> 14 * 15 * Based on 16 * Linux/m68k by Hamish Macdonald 17 */ 18 19/* 20 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 21 * Atari :-) Current limitation: Only one sigstack can be active at one time. 22 * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 23 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 24 * signal handlers! 25 */ 26 27#include <linux/sched.h> 28#include <linux/mm.h> 29#include <linux/kernel.h> 30#include <linux/signal.h> 31#include <linux/syscalls.h> 32#include <linux/errno.h> 33#include <linux/wait.h> 34#include <linux/ptrace.h> 35#include <linux/unistd.h> 36#include <linux/stddef.h> 37#include <linux/highuid.h> 38#include <linux/personality.h> 39#include <linux/tty.h> 40#include <linux/binfmts.h> 41#include <linux/freezer.h> 42 43#include <asm/setup.h> 44#include <asm/uaccess.h> 45#include <asm/pgtable.h> 46#include <asm/traps.h> 47#include <asm/ucontext.h> 48 49#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 50 51asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 52 53/* 54 * Atomically swap in the new signal mask, and wait for a signal. 55 */ 56asmlinkage int do_sigsuspend(struct pt_regs *regs) 57{ 58 old_sigset_t mask = regs->er3; 59 sigset_t saveset; 60 61 mask &= _BLOCKABLE; 62 spin_lock_irq(¤t->sighand->siglock); 63 saveset = current->blocked; 64 siginitset(¤t->blocked, mask); 65 recalc_sigpending(); 66 spin_unlock_irq(¤t->sighand->siglock); 67 68 regs->er0 = -EINTR; 69 while (1) { 70 current->state = TASK_INTERRUPTIBLE; 71 schedule(); 72 if (do_signal(regs, &saveset)) 73 return -EINTR; 74 } 75} 76 77asmlinkage int 78do_rt_sigsuspend(struct pt_regs *regs) 79{ 80 sigset_t *unewset = (sigset_t *)regs->er1; 81 size_t sigsetsize = (size_t)regs->er2; 82 sigset_t saveset, newset; 83 84 if (sigsetsize != sizeof(sigset_t)) 85 return -EINVAL; 86 87 if (copy_from_user(&newset, unewset, sizeof(newset))) 88 return -EFAULT; 89 sigdelsetmask(&newset, ~_BLOCKABLE); 90 91 spin_lock_irq(¤t->sighand->siglock); 92 saveset = current->blocked; 93 current->blocked = newset; 94 recalc_sigpending(); 95 spin_unlock_irq(¤t->sighand->siglock); 96 97 regs->er0 = -EINTR; 98 while (1) { 99 current->state = TASK_INTERRUPTIBLE; 100 schedule(); 101 if (do_signal(regs, &saveset)) 102 return -EINTR; 103 } 104} 105 106asmlinkage int 107sys_sigaction(int sig, const struct old_sigaction *act, 108 struct old_sigaction *oact) 109{ 110 struct k_sigaction new_ka, old_ka; 111 int ret; 112 113 if (act) { 114 old_sigset_t mask; 115 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 116 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 117 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 118 return -EFAULT; 119 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 120 __get_user(mask, &act->sa_mask); 121 siginitset(&new_ka.sa.sa_mask, mask); 122 } 123 124 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 125 126 if (!ret && oact) { 127 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 128 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 129 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 130 return -EFAULT; 131 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 132 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 133 } 134 135 return ret; 136} 137 138asmlinkage int 139sys_sigaltstack(const stack_t *uss, stack_t *uoss) 140{ 141 return do_sigaltstack(uss, uoss, rdusp()); 142} 143 144 145/* 146 * Do a signal return; undo the signal stack. 147 * 148 * Keep the return code on the stack quadword aligned! 149 * That makes the cache flush below easier. 150 */ 151 152struct sigframe 153{ 154 long dummy_er0; 155 long dummy_vector; 156#if defined(CONFIG_CPU_H8S) 157 short dummy_exr; 158#endif 159 long dummy_pc; 160 char *pretcode; 161 unsigned char retcode[8]; 162 unsigned long extramask[_NSIG_WORDS-1]; 163 struct sigcontext sc; 164 int sig; 165} __attribute__((aligned(2),packed)); 166 167struct rt_sigframe 168{ 169 long dummy_er0; 170 long dummy_vector; 171#if defined(CONFIG_CPU_H8S) 172 short dummy_exr; 173#endif 174 long dummy_pc; 175 char *pretcode; 176 struct siginfo *pinfo; 177 void *puc; 178 unsigned char retcode[8]; 179 struct siginfo info; 180 struct ucontext uc; 181 int sig; 182} __attribute__((aligned(2),packed)); 183 184static inline int 185restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, 186 int *pd0) 187{ 188 int err = 0; 189 unsigned int ccr; 190 unsigned int usp; 191 unsigned int er0; 192 193 /* Always make any pending restarted system calls return -EINTR */ 194 current_thread_info()->restart_block.fn = do_no_restart_syscall; 195 196#define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */ 197 COPY(er1); 198 COPY(er2); 199 COPY(er3); 200 COPY(er5); 201 COPY(pc); 202 ccr = regs->ccr & 0x10; 203 COPY(ccr); 204#undef COPY 205 regs->ccr &= 0xef; 206 regs->ccr |= ccr; 207 regs->orig_er0 = -1; /* disable syscall checks */ 208 err |= __get_user(usp, &usc->sc_usp); 209 wrusp(usp); 210 211 err |= __get_user(er0, &usc->sc_er0); 212 *pd0 = er0; 213 return err; 214} 215 216asmlinkage int do_sigreturn(unsigned long __unused,...) 217{ 218 struct pt_regs *regs = (struct pt_regs *) (&__unused - 1); 219 unsigned long usp = rdusp(); 220 struct sigframe *frame = (struct sigframe *)(usp - 4); 221 sigset_t set; 222 int er0; 223 224 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 225 goto badframe; 226 if (__get_user(set.sig[0], &frame->sc.sc_mask) || 227 (_NSIG_WORDS > 1 && 228 __copy_from_user(&set.sig[1], &frame->extramask, 229 sizeof(frame->extramask)))) 230 goto badframe; 231 232 sigdelsetmask(&set, ~_BLOCKABLE); 233 spin_lock_irq(¤t->sighand->siglock); 234 current->blocked = set; 235 recalc_sigpending(); 236 spin_unlock_irq(¤t->sighand->siglock); 237 238 if (restore_sigcontext(regs, &frame->sc, &er0)) 239 goto badframe; 240 return er0; 241 242badframe: 243 force_sig(SIGSEGV, current); 244 return 0; 245} 246 247asmlinkage int do_rt_sigreturn(unsigned long __unused,...) 248{ 249 struct pt_regs *regs = (struct pt_regs *) &__unused; 250 unsigned long usp = rdusp(); 251 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); 252 sigset_t set; 253 int er0; 254 255 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 256 goto badframe; 257 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 258 goto badframe; 259 260 sigdelsetmask(&set, ~_BLOCKABLE); 261 spin_unlock_irq(¤t->sighand->siglock); 262 current->blocked = set; 263 recalc_sigpending(); 264 spin_lock_irq(¤t->sighand->siglock); 265 266 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0)) 267 goto badframe; 268 269 if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT) 270 goto badframe; 271 272 return er0; 273 274badframe: 275 force_sig(SIGSEGV, current); 276 return 0; 277} 278 279static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 280 unsigned long mask) 281{ 282 int err = 0; 283 284 err |= __put_user(regs->er0, &sc->sc_er0); 285 err |= __put_user(regs->er1, &sc->sc_er1); 286 err |= __put_user(regs->er2, &sc->sc_er2); 287 err |= __put_user(regs->er3, &sc->sc_er3); 288 err |= __put_user(regs->er4, &sc->sc_er4); 289 err |= __put_user(regs->er5, &sc->sc_er5); 290 err |= __put_user(regs->er6, &sc->sc_er6); 291 err |= __put_user(rdusp(), &sc->sc_usp); 292 err |= __put_user(regs->pc, &sc->sc_pc); 293 err |= __put_user(regs->ccr, &sc->sc_ccr); 294 err |= __put_user(mask, &sc->sc_mask); 295 296 return err; 297} 298 299static inline void * 300get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 301{ 302 unsigned long usp; 303 304 /* Default to using normal stack. */ 305 usp = rdusp(); 306 307 /* This is the X/Open sanctioned signal stack switching. */ 308 if (ka->sa.sa_flags & SA_ONSTACK) { 309 if (!sas_ss_flags(usp)) 310 usp = current->sas_ss_sp + current->sas_ss_size; 311 } 312 return (void *)((usp - frame_size) & -8UL); 313} 314 315static void setup_frame (int sig, struct k_sigaction *ka, 316 sigset_t *set, struct pt_regs *regs) 317{ 318 struct sigframe *frame; 319 int err = 0; 320 int usig; 321 unsigned char *ret; 322 323 frame = get_sigframe(ka, regs, sizeof(*frame)); 324 325 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 326 goto give_sigsegv; 327 328 usig = current_thread_info()->exec_domain 329 && current_thread_info()->exec_domain->signal_invmap 330 && sig < 32 331 ? current_thread_info()->exec_domain->signal_invmap[sig] 332 : sig; 333 334 err |= __put_user(usig, &frame->sig); 335 if (err) 336 goto give_sigsegv; 337 338 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); 339 if (err) 340 goto give_sigsegv; 341 342 if (_NSIG_WORDS > 1) { 343 err |= copy_to_user(frame->extramask, &set->sig[1], 344 sizeof(frame->extramask)); 345 if (err) 346 goto give_sigsegv; 347 } 348 349 ret = frame->retcode; 350 if (ka->sa.sa_flags & SA_RESTORER) 351 ret = (unsigned char *)(ka->sa.sa_restorer); 352 else { 353 /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ 354 err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), 355 (unsigned long *)(frame->retcode + 0)); 356 err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); 357 } 358 359 /* Set up to return from userspace. */ 360 err |= __put_user(ret, &frame->pretcode); 361 362 if (err) 363 goto give_sigsegv; 364 365 /* Set up registers for signal handler */ 366 wrusp ((unsigned long) frame); 367 regs->pc = (unsigned long) ka->sa.sa_handler; 368 regs->er0 = (current_thread_info()->exec_domain 369 && current_thread_info()->exec_domain->signal_invmap 370 && sig < 32 371 ? current_thread_info()->exec_domain->signal_invmap[sig] 372 : sig); 373 regs->er1 = (unsigned long)&(frame->sc); 374 regs->er5 = current->mm->start_data; /* GOT base */ 375 376 return; 377 378give_sigsegv: 379 force_sigsegv(sig, current); 380} 381 382static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 383 sigset_t *set, struct pt_regs *regs) 384{ 385 struct rt_sigframe *frame; 386 int err = 0; 387 int usig; 388 unsigned char *ret; 389 390 frame = get_sigframe(ka, regs, sizeof(*frame)); 391 392 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 393 goto give_sigsegv; 394 395 usig = current_thread_info()->exec_domain 396 && current_thread_info()->exec_domain->signal_invmap 397 && sig < 32 398 ? current_thread_info()->exec_domain->signal_invmap[sig] 399 : sig; 400 401 err |= __put_user(usig, &frame->sig); 402 if (err) 403 goto give_sigsegv; 404 405 err |= __put_user(&frame->info, &frame->pinfo); 406 err |= __put_user(&frame->uc, &frame->puc); 407 err |= copy_siginfo_to_user(&frame->info, info); 408 if (err) 409 goto give_sigsegv; 410 411 /* Create the ucontext. */ 412 err |= __put_user(0, &frame->uc.uc_flags); 413 err |= __put_user(0, &frame->uc.uc_link); 414 err |= __put_user((void *)current->sas_ss_sp, 415 &frame->uc.uc_stack.ss_sp); 416 err |= __put_user(sas_ss_flags(rdusp()), 417 &frame->uc.uc_stack.ss_flags); 418 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 419 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); 420 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 421 if (err) 422 goto give_sigsegv; 423 424 /* Set up to return from userspace. */ 425 ret = frame->retcode; 426 if (ka->sa.sa_flags & SA_RESTORER) 427 ret = (unsigned char *)(ka->sa.sa_restorer); 428 else { 429 /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ 430 err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), 431 (unsigned long *)(frame->retcode + 0)); 432 err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); 433 } 434 err |= __put_user(ret, &frame->pretcode); 435 436 if (err) 437 goto give_sigsegv; 438 439 /* Set up registers for signal handler */ 440 wrusp ((unsigned long) frame); 441 regs->pc = (unsigned long) ka->sa.sa_handler; 442 regs->er0 = (current_thread_info()->exec_domain 443 && current_thread_info()->exec_domain->signal_invmap 444 && sig < 32 445 ? current_thread_info()->exec_domain->signal_invmap[sig] 446 : sig); 447 regs->er1 = (unsigned long)&(frame->info); 448 regs->er2 = (unsigned long)&frame->uc; 449 regs->er5 = current->mm->start_data; /* GOT base */ 450 451 return; 452 453give_sigsegv: 454 force_sigsegv(sig, current); 455} 456 457/* 458 * OK, we're invoking a handler 459 */ 460static void 461handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 462 sigset_t *oldset, struct pt_regs * regs) 463{ 464 /* are we from a system call? */ 465 if (regs->orig_er0 >= 0) { 466 switch (regs->er0) { 467 case -ERESTART_RESTARTBLOCK: 468 case -ERESTARTNOHAND: 469 regs->er0 = -EINTR; 470 break; 471 472 case -ERESTARTSYS: 473 if (!(ka->sa.sa_flags & SA_RESTART)) { 474 regs->er0 = -EINTR; 475 break; 476 } 477 /* fallthrough */ 478 case -ERESTARTNOINTR: 479 regs->er0 = regs->orig_er0; 480 regs->pc -= 2; 481 } 482 } 483 484 /* set up the stack frame */ 485 if (ka->sa.sa_flags & SA_SIGINFO) 486 setup_rt_frame(sig, ka, info, oldset, regs); 487 else 488 setup_frame(sig, ka, oldset, regs); 489 490 spin_lock_irq(¤t->sighand->siglock); 491 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); 492 if (!(ka->sa.sa_flags & SA_NODEFER)) 493 sigaddset(¤t->blocked,sig); 494 recalc_sigpending(); 495 spin_unlock_irq(¤t->sighand->siglock); 496} 497 498/* 499 * Note that 'init' is a special process: it doesn't get signals it doesn't 500 * want to handle. Thus you cannot kill init even with a SIGKILL even by 501 * mistake. 502 */ 503asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset) 504{ 505 siginfo_t info; 506 int signr; 507 struct k_sigaction ka; 508 509 /* 510 * We want the common case to go fast, which 511 * is why we may in certain cases get here from 512 * kernel mode. Just return without doing anything 513 * if so. 514 */ 515 if ((regs->ccr & 0x10)) 516 return 1; 517 518 if (try_to_freeze()) 519 goto no_signal; 520 521 current->thread.esp0 = (unsigned long) regs; 522 523 if (!oldset) 524 oldset = ¤t->blocked; 525 526 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 527 if (signr > 0) { 528 /* Whee! Actually deliver the signal. */ 529 handle_signal(signr, &info, &ka, oldset, regs); 530 return 1; 531 } 532 no_signal: 533 /* Did we come from a system call? */ 534 if (regs->orig_er0 >= 0) { 535 /* Restart the system call - no handlers present */ 536 if (regs->er0 == -ERESTARTNOHAND || 537 regs->er0 == -ERESTARTSYS || 538 regs->er0 == -ERESTARTNOINTR) { 539 regs->er0 = regs->orig_er0; 540 regs->pc -= 2; 541 } 542 if (regs->er0 == -ERESTART_RESTARTBLOCK){ 543 regs->er0 = __NR_restart_syscall; 544 regs->pc -= 2; 545 } 546 } 547 return 0; 548} 549