Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

CRIS v10: correct do_signal to fix oops and clean up signal handling in general

This fixes a kernel panic on boot due to do_signal not being compatible
with it's callers.

- do_signal now returns void, and does not have the previous signal set
as a parameter.
- Remove sys_rt_sigsuspend, we can use the common one instead.
- Change sys_sigsuspend to be more like x86, don't call do_signal here.
- handle_signal, setup_frame and setup_rt_frame now return -EFAULT
if we've delivered a segfault, which is used by callers to perform
necessary cleanup.
- Break long lines, correct whitespace and formatting errors.

Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Mikael Starvik <mikael.starvik@axis.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jesper Nilsson and committed by
Linus Torvalds
a4858d4d 3ea0345b

+110 -137
+110 -137
arch/cris/arch-v10/kernel/signal.c
··· 7 7 * 8 8 * Ideas also taken from arch/arm. 9 9 * 10 - * Copyright (C) 2000, 2001 Axis Communications AB 10 + * Copyright (C) 2000-2007 Axis Communications AB 11 11 * 12 12 * Authors: Bjorn Wesen (bjornw@axis.com) 13 13 * ··· 40 40 */ 41 41 #define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2; 42 42 43 - int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs); 43 + void do_signal(int canrestart, struct pt_regs *regs); 44 44 45 45 /* 46 - * Atomically swap in the new signal mask, and wait for a signal. Define 46 + * Atomically swap in the new signal mask, and wait for a signal. Define 47 47 * dummy arguments to be able to reach the regs argument. (Note that this 48 48 * arrangement relies on old_sigset_t occupying one register.) 49 49 */ 50 - int 51 - sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 52 - long srp, struct pt_regs *regs) 50 + int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 51 + long srp, struct pt_regs *regs) 53 52 { 54 - sigset_t saveset; 55 - 56 53 mask &= _BLOCKABLE; 57 54 spin_lock_irq(&current->sighand->siglock); 58 - saveset = current->blocked; 55 + current->saved_sigmask = current->blocked; 59 56 siginitset(&current->blocked, mask); 60 57 recalc_sigpending(); 61 58 spin_unlock_irq(&current->sighand->siglock); 62 - 63 - regs->r10 = -EINTR; 64 - while (1) { 65 - current->state = TASK_INTERRUPTIBLE; 66 - schedule(); 67 - if (do_signal(0, &saveset, regs)) 68 - /* We will get here twice: once to call the signal 69 - handler, then again to return from the 70 - sigsuspend system call. When calling the 71 - signal handler, R10 holds the signal number as 72 - set through do_signal. The sigsuspend call 73 - will return with the restored value set above; 74 - always -EINTR. */ 75 - return regs->r10; 76 - } 59 + current->state = TASK_INTERRUPTIBLE; 60 + schedule(); 61 + set_thread_flag(TIF_RESTORE_SIGMASK); 62 + return -ERESTARTNOHAND; 77 63 } 78 64 79 - /* Define dummy arguments to be able to reach the regs argument. (Note that 80 - * this arrangement relies on size_t occupying one register.) 81 - */ 82 - int 83 - sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13, 84 - long mof, long srp, struct pt_regs *regs) 85 - { 86 - sigset_t saveset, newset; 87 - 88 - /* XXX: Don't preclude handling different sized sigset_t's. */ 89 - if (sigsetsize != sizeof(sigset_t)) 90 - return -EINVAL; 91 - 92 - if (copy_from_user(&newset, unewset, sizeof(newset))) 93 - return -EFAULT; 94 - sigdelsetmask(&newset, ~_BLOCKABLE); 95 - 96 - spin_lock_irq(&current->sighand->siglock); 97 - saveset = current->blocked; 98 - current->blocked = newset; 99 - recalc_sigpending(); 100 - spin_unlock_irq(&current->sighand->siglock); 101 - 102 - regs->r10 = -EINTR; 103 - while (1) { 104 - current->state = TASK_INTERRUPTIBLE; 105 - schedule(); 106 - if (do_signal(0, &saveset, regs)) 107 - /* We will get here twice: once to call the signal 108 - handler, then again to return from the 109 - sigsuspend system call. When calling the 110 - signal handler, R10 holds the signal number as 111 - set through do_signal. The sigsuspend call 112 - will return with the restored value set above; 113 - always -EINTR. */ 114 - return regs->r10; 115 - } 116 - } 117 - 118 - int 119 - sys_sigaction(int sig, const struct old_sigaction __user *act, 120 - struct old_sigaction *oact) 65 + int sys_sigaction(int sig, const struct old_sigaction __user *act, 66 + struct old_sigaction *oact) 121 67 { 122 68 struct k_sigaction new_ka, old_ka; 123 69 int ret; ··· 93 147 return ret; 94 148 } 95 149 96 - int 97 - sys_sigaltstack(const stack_t *uss, stack_t __user *uoss) 150 + int sys_sigaltstack(const stack_t *uss, stack_t __user *uoss) 98 151 { 99 152 return do_sigaltstack(uss, uoss, rdusp()); 100 153 } ··· 150 205 151 206 /* TODO: the other ports use regs->orig_XX to disable syscall checks 152 207 * after this completes, but we don't use that mechanism. maybe we can 153 - * use it now ? 208 + * use it now ? 154 209 */ 155 210 156 211 return err; ··· 161 216 162 217 /* Define dummy arguments to be able to reach the regs argument. */ 163 218 164 - asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, 219 + asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, 165 220 long srp, struct pt_regs *regs) 166 221 { 167 222 struct sigframe __user *frame = (struct sigframe *)rdusp(); ··· 188 243 current->blocked = set; 189 244 recalc_sigpending(); 190 245 spin_unlock_irq(&current->sighand->siglock); 191 - 246 + 192 247 if (restore_sigcontext(regs, &frame->sc)) 193 248 goto badframe; 194 249 ··· 199 254 badframe: 200 255 force_sig(SIGSEGV, current); 201 256 return 0; 202 - } 257 + } 203 258 204 259 /* Define dummy arguments to be able to reach the regs argument. */ 205 260 206 - asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, 261 + asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, 207 262 long mof, long srp, struct pt_regs *regs) 208 263 { 209 264 struct rt_sigframe __user *frame = (struct rt_sigframe *)rdusp(); ··· 227 282 current->blocked = set; 228 283 recalc_sigpending(); 229 284 spin_unlock_irq(&current->sighand->siglock); 230 - 285 + 231 286 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 232 287 goto badframe; 233 288 ··· 239 294 badframe: 240 295 force_sig(SIGSEGV, current); 241 296 return 0; 242 - } 297 + } 243 298 244 299 /* 245 300 * Set up a signal frame. 246 301 */ 247 302 248 - static int 249 - setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask) 303 + static int setup_sigcontext(struct sigcontext __user *sc, 304 + struct pt_regs *regs, unsigned long mask) 250 305 { 251 306 int err = 0; 252 307 unsigned long usp = rdusp(); ··· 269 324 return err; 270 325 } 271 326 272 - /* figure out where we want to put the new signal frame - usually on the stack */ 327 + /* Figure out where we want to put the new signal frame 328 + * - usually on the stack. */ 273 329 274 330 static inline void __user * 275 - get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) 331 + get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 276 332 { 277 333 unsigned long sp = rdusp(); 278 334 ··· 291 345 } 292 346 293 347 /* grab and setup a signal frame. 294 - * 348 + * 295 349 * basically we stack a lot of state info, and arrange for the 296 350 * user-mode program to return to the kernel using either a 297 351 * trampoline which performs the syscall sigreturn, or a provided 298 352 * user-mode trampoline. 299 353 */ 300 354 301 - static void setup_frame(int sig, struct k_sigaction *ka, 302 - sigset_t *set, struct pt_regs * regs) 355 + static int setup_frame(int sig, struct k_sigaction *ka, 356 + sigset_t *set, struct pt_regs *regs) 303 357 { 304 358 struct sigframe __user *frame; 305 359 unsigned long return_ip; ··· 347 401 348 402 wrusp((unsigned long)frame); 349 403 350 - return; 404 + return 0; 351 405 352 406 give_sigsegv: 353 407 force_sigsegv(sig, current); 408 + return -EFAULT; 354 409 } 355 410 356 - static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 357 - sigset_t *set, struct pt_regs * regs) 411 + static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 412 + sigset_t *set, struct pt_regs *regs) 358 413 { 359 414 struct rt_sigframe __user *frame; 360 415 unsigned long return_ip; ··· 390 443 /* trampoline - the desired return ip is the retcode itself */ 391 444 return_ip = (unsigned long)&frame->retcode; 392 445 /* This is movu.w __NR_rt_sigreturn, r9; break 13; */ 393 - err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0)); 394 - err |= __put_user(__NR_rt_sigreturn, (short __user*)(frame->retcode+2)); 395 - err |= __put_user(0xe93d, (short __user*)(frame->retcode+4)); 446 + err |= __put_user(0x9c5f, (short __user *)(frame->retcode+0)); 447 + err |= __put_user(__NR_rt_sigreturn, 448 + (short __user *)(frame->retcode+2)); 449 + err |= __put_user(0xe93d, (short __user *)(frame->retcode+4)); 396 450 } 397 451 398 452 if (err) ··· 403 455 404 456 /* Set up registers for signal handler */ 405 457 406 - regs->irp = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ 407 - regs->srp = return_ip; /* what we enter LATER */ 408 - regs->r10 = sig; /* first argument is signo */ 409 - regs->r11 = (unsigned long) &frame->info; /* second argument is (siginfo_t *) */ 410 - regs->r12 = 0; /* third argument is unused */ 458 + /* What we enter NOW */ 459 + regs->irp = (unsigned long) ka->sa.sa_handler; 460 + /* What we enter LATER */ 461 + regs->srp = return_ip; 462 + /* First argument is signo */ 463 + regs->r10 = sig; 464 + /* Second argument is (siginfo_t *) */ 465 + regs->r11 = (unsigned long)&frame->info; 466 + /* Third argument is unused */ 467 + regs->r12 = 0; 411 468 412 - /* actually move the usp to reflect the stacked frame */ 413 - 469 + /* Actually move the usp to reflect the stacked frame */ 414 470 wrusp((unsigned long)frame); 415 471 416 - return; 472 + return 0; 417 473 418 474 give_sigsegv: 419 475 force_sigsegv(sig, current); 476 + return -EFAULT; 420 477 } 421 478 422 479 /* 423 480 * OK, we're invoking a handler 424 - */ 481 + */ 425 482 426 - static inline void 427 - handle_signal(int canrestart, unsigned long sig, 428 - siginfo_t *info, struct k_sigaction *ka, 429 - sigset_t *oldset, struct pt_regs * regs) 483 + static inline int handle_signal(int canrestart, unsigned long sig, 484 + siginfo_t *info, struct k_sigaction *ka, 485 + sigset_t *oldset, struct pt_regs *regs) 430 486 { 487 + int ret; 488 + 431 489 /* Are we from a system call? */ 432 490 if (canrestart) { 433 491 /* If so, check system call restarting.. */ 434 492 switch (regs->r10) { 435 - case -ERESTART_RESTARTBLOCK: 436 - case -ERESTARTNOHAND: 437 - /* ERESTARTNOHAND means that the syscall should only be 438 - restarted if there was no handler for the signal, and since 439 - we only get here if there is a handler, we don't restart */ 493 + case -ERESTART_RESTARTBLOCK: 494 + case -ERESTARTNOHAND: 495 + /* ERESTARTNOHAND means that the syscall should 496 + * only be restarted if there was no handler for 497 + * the signal, and since we only get here if there 498 + * is a handler, we don't restart */ 499 + regs->r10 = -EINTR; 500 + break; 501 + case -ERESTARTSYS: 502 + /* ERESTARTSYS means to restart the syscall if 503 + * there is no handler or the handler was 504 + * registered with SA_RESTART */ 505 + if (!(ka->sa.sa_flags & SA_RESTART)) { 440 506 regs->r10 = -EINTR; 441 507 break; 442 - 443 - case -ERESTARTSYS: 444 - /* ERESTARTSYS means to restart the syscall if there is no 445 - handler or the handler was registered with SA_RESTART */ 446 - if (!(ka->sa.sa_flags & SA_RESTART)) { 447 - regs->r10 = -EINTR; 448 - break; 449 - } 450 - /* fallthrough */ 451 - case -ERESTARTNOINTR: 452 - /* ERESTARTNOINTR means that the syscall should be called again 453 - after the signal handler returns. */ 454 - RESTART_CRIS_SYS(regs); 508 + } 509 + /* fallthrough */ 510 + case -ERESTARTNOINTR: 511 + /* ERESTARTNOINTR means that the syscall should 512 + * be called again after the signal handler returns. */ 513 + RESTART_CRIS_SYS(regs); 455 514 } 456 515 } 457 516 458 517 /* Set up the stack frame */ 459 518 if (ka->sa.sa_flags & SA_SIGINFO) 460 - setup_rt_frame(sig, ka, info, oldset, regs); 519 + ret = setup_rt_frame(sig, ka, info, oldset, regs); 461 520 else 462 - setup_frame(sig, ka, oldset, regs); 521 + ret = setup_frame(sig, ka, oldset, regs); 463 522 464 - if (ka->sa.sa_flags & SA_ONESHOT) 465 - ka->sa.sa_handler = SIG_DFL; 466 - 467 - spin_lock_irq(&current->sighand->siglock); 468 - sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 469 - if (!(ka->sa.sa_flags & SA_NODEFER)) 470 - sigaddset(&current->blocked,sig); 471 - recalc_sigpending(); 472 - spin_unlock_irq(&current->sighand->siglock); 523 + if (ret == 0) { 524 + spin_lock_irq(&current->sighand->siglock); 525 + sigorsets(&current->blocked, &current->blocked, 526 + &ka->sa.sa_mask); 527 + if (!(ka->sa.sa_flags & SA_NODEFER)) 528 + sigaddset(&current->blocked, sig); 529 + recalc_sigpending(); 530 + spin_unlock_irq(&current->sighand->siglock); 531 + } 532 + return ret; 473 533 } 474 534 475 535 /* ··· 492 536 * mode below. 493 537 */ 494 538 495 - int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) 539 + void do_signal(int canrestart, struct pt_regs *regs) 496 540 { 497 541 siginfo_t info; 498 542 int signr; 499 543 struct k_sigaction ka; 544 + sigset_t *oldset; 500 545 501 546 /* 502 547 * We want the common case to go fast, which ··· 506 549 * if so. 507 550 */ 508 551 if (!user_mode(regs)) 509 - return 1; 552 + return; 510 553 511 - if (!oldset) 554 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) 555 + oldset = &current->saved_sigmask; 556 + else 512 557 oldset = &current->blocked; 513 558 514 559 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 515 560 if (signr > 0) { 516 561 /* Whee! Actually deliver the signal. */ 517 - handle_signal(canrestart, signr, &info, &ka, oldset, regs); 518 - return 1; 562 + if (handle_signal(canrestart, signr, &info, &ka, 563 + oldset, regs)) { 564 + /* a signal was successfully delivered; the saved 565 + * sigmask will have been stored in the signal frame, 566 + * and will be restored by sigreturn, so we can simply 567 + * clear the TIF_RESTORE_SIGMASK flag */ 568 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) 569 + clear_thread_flag(TIF_RESTORE_SIGMASK); 570 + } 571 + return; 519 572 } 520 573 521 574 /* Did we come from a system call? */ ··· 536 569 regs->r10 == -ERESTARTNOINTR) { 537 570 RESTART_CRIS_SYS(regs); 538 571 } 539 - if (regs->r10 == -ERESTART_RESTARTBLOCK){ 572 + if (regs->r10 == -ERESTART_RESTARTBLOCK) { 540 573 regs->r10 = __NR_restart_syscall; 541 574 regs->irp -= 2; 542 575 } 543 576 } 544 - return 0; 577 + 578 + /* if there's no signal to deliver, we just put the saved sigmask 579 + * back */ 580 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 581 + clear_thread_flag(TIF_RESTORE_SIGMASK); 582 + sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 583 + } 545 584 }