1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1991, 1992 Linus Torvalds 7 * Copyright (C) 1994 - 2000 Ralf Baechle 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 9 */ 10 #include <linux/config.h> 11 #include <linux/sched.h> 12 #include <linux/mm.h> 13 #include <linux/personality.h> 14 #include <linux/smp.h> 15 #include <linux/smp_lock.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/compiler.h> 23 24 #include <asm/asm.h> 25 #include <linux/bitops.h> 26 #include <asm/cacheflush.h> 27 #include <asm/fpu.h> 28 #include <asm/sim.h> 29 #include <asm/uaccess.h> 30 #include <asm/ucontext.h> 31 #include <asm/cpu-features.h> 32 33 #include "signal-common.h" 34 35 #define DEBUG_SIG 0 36 37 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 38 39 static int do_signal(sigset_t *oldset, struct pt_regs *regs); 40 41 /* 42 * Atomically swap in the new signal mask, and wait for a signal. 43 */ 44 45 #ifdef CONFIG_TRAD_SIGNALS 46 save_static_function(sys_sigsuspend); 47 __attribute_used__ noinline static int 48 _sys_sigsuspend(nabi_no_regargs struct pt_regs regs) 49 { 50 sigset_t *uset, saveset, newset; 51 52 uset = (sigset_t *) regs.regs[4]; 53 if (copy_from_user(&newset, uset, sizeof(sigset_t))) 54 return -EFAULT; 55 sigdelsetmask(&newset, ~_BLOCKABLE); 56 57 spin_lock_irq(¤t->sighand->siglock); 58 saveset = current->blocked; 59 current->blocked = newset; 60 recalc_sigpending(); 61 spin_unlock_irq(¤t->sighand->siglock); 62 63 regs.regs[2] = EINTR; 64 regs.regs[7] = 1; 65 while (1) { 66 current->state = TASK_INTERRUPTIBLE; 67 schedule(); 68 if (do_signal(&saveset, ®s)) 69 return -EINTR; 70 } 71 } 72 #endif 73 74 save_static_function(sys_rt_sigsuspend); 75 __attribute_used__ noinline static int 76 _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) 77 { 78 sigset_t *unewset, saveset, newset; 79 size_t sigsetsize; 80 81 /* XXX Don't preclude handling different sized sigset_t's. */ 82 sigsetsize = regs.regs[5]; 83 if (sigsetsize != sizeof(sigset_t)) 84 return -EINVAL; 85 86 unewset = (sigset_t *) regs.regs[4]; 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.regs[2] = EINTR; 98 regs.regs[7] = 1; 99 while (1) { 100 current->state = TASK_INTERRUPTIBLE; 101 schedule(); 102 if (do_signal(&saveset, ®s)) 103 return -EINTR; 104 } 105 } 106 107 #ifdef CONFIG_TRAD_SIGNALS 108 asmlinkage int sys_sigaction(int sig, const struct sigaction *act, 109 struct sigaction *oact) 110 { 111 struct k_sigaction new_ka, old_ka; 112 int ret; 113 int err = 0; 114 115 if (act) { 116 old_sigset_t mask; 117 118 if (!access_ok(VERIFY_READ, act, sizeof(*act))) 119 return -EFAULT; 120 err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); 121 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); 122 err |= __get_user(mask, &act->sa_mask.sig[0]); 123 if (err) 124 return -EFAULT; 125 126 siginitset(&new_ka.sa.sa_mask, mask); 127 } 128 129 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 130 131 if (!ret && oact) { 132 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) 133 return -EFAULT; 134 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 135 err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler); 136 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig); 137 err |= __put_user(0, &oact->sa_mask.sig[1]); 138 err |= __put_user(0, &oact->sa_mask.sig[2]); 139 err |= __put_user(0, &oact->sa_mask.sig[3]); 140 if (err) 141 return -EFAULT; 142 } 143 144 return ret; 145 } 146 #endif 147 148 asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs) 149 { 150 const stack_t *uss = (const stack_t *) regs.regs[4]; 151 stack_t *uoss = (stack_t *) regs.regs[5]; 152 unsigned long usp = regs.regs[29]; 153 154 return do_sigaltstack(uss, uoss, usp); 155 } 156 157 #if PLAT_TRAMPOLINE_STUFF_LINE 158 #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE))) 159 #else 160 #define __tramp 161 #endif 162 163 #ifdef CONFIG_TRAD_SIGNALS 164 struct sigframe { 165 u32 sf_ass[4]; /* argument save space for o32 */ 166 u32 sf_code[2] __tramp; /* signal trampoline */ 167 struct sigcontext sf_sc __tramp; 168 sigset_t sf_mask; 169 }; 170 #endif 171 172 struct rt_sigframe { 173 u32 rs_ass[4]; /* argument save space for o32 */ 174 u32 rs_code[2] __tramp; /* signal trampoline */ 175 struct siginfo rs_info __tramp; 176 struct ucontext rs_uc; 177 }; 178 179 #ifdef CONFIG_TRAD_SIGNALS 180 save_static_function(sys_sigreturn); 181 __attribute_used__ noinline static void 182 _sys_sigreturn(nabi_no_regargs struct pt_regs regs) 183 { 184 struct sigframe *frame; 185 sigset_t blocked; 186 187 frame = (struct sigframe *) regs.regs[29]; 188 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 189 goto badframe; 190 if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) 191 goto badframe; 192 193 sigdelsetmask(&blocked, ~_BLOCKABLE); 194 spin_lock_irq(¤t->sighand->siglock); 195 current->blocked = blocked; 196 recalc_sigpending(); 197 spin_unlock_irq(¤t->sighand->siglock); 198 199 if (restore_sigcontext(®s, &frame->sf_sc)) 200 goto badframe; 201 202 /* 203 * Don't let your children do this ... 204 */ 205 if (current_thread_info()->flags & TIF_SYSCALL_TRACE) 206 do_syscall_trace(®s, 1); 207 __asm__ __volatile__( 208 "move\t$29, %0\n\t" 209 "j\tsyscall_exit" 210 :/* no outputs */ 211 :"r" (®s)); 212 /* Unreached */ 213 214 badframe: 215 force_sig(SIGSEGV, current); 216 } 217 #endif 218 219 save_static_function(sys_rt_sigreturn); 220 __attribute_used__ noinline static void 221 _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) 222 { 223 struct rt_sigframe *frame; 224 sigset_t set; 225 stack_t st; 226 227 frame = (struct rt_sigframe *) regs.regs[29]; 228 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 229 goto badframe; 230 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) 231 goto badframe; 232 233 sigdelsetmask(&set, ~_BLOCKABLE); 234 spin_lock_irq(¤t->sighand->siglock); 235 current->blocked = set; 236 recalc_sigpending(); 237 spin_unlock_irq(¤t->sighand->siglock); 238 239 if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) 240 goto badframe; 241 242 if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) 243 goto badframe; 244 /* It is more difficult to avoid calling this function than to 245 call it and ignore errors. */ 246 do_sigaltstack(&st, NULL, regs.regs[29]); 247 248 /* 249 * Don't let your children do this ... 250 */ 251 __asm__ __volatile__( 252 "move\t$29, %0\n\t" 253 "j\tsyscall_exit" 254 :/* no outputs */ 255 :"r" (®s)); 256 /* Unreached */ 257 258 badframe: 259 force_sig(SIGSEGV, current); 260 } 261 262 #ifdef CONFIG_TRAD_SIGNALS 263 static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, 264 int signr, sigset_t *set) 265 { 266 struct sigframe *frame; 267 int err = 0; 268 269 frame = get_sigframe(ka, regs, sizeof(*frame)); 270 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 271 goto give_sigsegv; 272 273 /* 274 * Set up the return code ... 275 * 276 * li v0, __NR_sigreturn 277 * syscall 278 */ 279 if (PLAT_TRAMPOLINE_STUFF_LINE) 280 __clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE); 281 err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0); 282 err |= __put_user(0x0000000c , frame->sf_code + 1); 283 flush_cache_sigtramp((unsigned long) frame->sf_code); 284 285 err |= setup_sigcontext(regs, &frame->sf_sc); 286 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); 287 if (err) 288 goto give_sigsegv; 289 290 /* 291 * Arguments to signal handler: 292 * 293 * a0 = signal number 294 * a1 = 0 (should be cause) 295 * a2 = pointer to struct sigcontext 296 * 297 * $25 and c0_epc point to the signal handler, $29 points to the 298 * struct sigframe. 299 */ 300 regs->regs[ 4] = signr; 301 regs->regs[ 5] = 0; 302 regs->regs[ 6] = (unsigned long) &frame->sf_sc; 303 regs->regs[29] = (unsigned long) frame; 304 regs->regs[31] = (unsigned long) frame->sf_code; 305 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 306 307 #if DEBUG_SIG 308 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", 309 current->comm, current->pid, 310 frame, regs->cp0_epc, frame->regs[31]); 311 #endif 312 return; 313 314 give_sigsegv: 315 force_sigsegv(signr, current); 316 } 317 #endif 318 319 static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 320 int signr, sigset_t *set, siginfo_t *info) 321 { 322 struct rt_sigframe *frame; 323 int err = 0; 324 325 frame = get_sigframe(ka, regs, sizeof(*frame)); 326 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 327 goto give_sigsegv; 328 329 /* 330 * Set up the return code ... 331 * 332 * li v0, __NR_rt_sigreturn 333 * syscall 334 */ 335 if (PLAT_TRAMPOLINE_STUFF_LINE) 336 __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE); 337 err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); 338 err |= __put_user(0x0000000c , frame->rs_code + 1); 339 flush_cache_sigtramp((unsigned long) frame->rs_code); 340 341 /* Create siginfo. */ 342 err |= copy_siginfo_to_user(&frame->rs_info, info); 343 344 /* Create the ucontext. */ 345 err |= __put_user(0, &frame->rs_uc.uc_flags); 346 err |= __put_user(0, &frame->rs_uc.uc_link); 347 err |= __put_user((void *)current->sas_ss_sp, 348 &frame->rs_uc.uc_stack.ss_sp); 349 err |= __put_user(sas_ss_flags(regs->regs[29]), 350 &frame->rs_uc.uc_stack.ss_flags); 351 err |= __put_user(current->sas_ss_size, 352 &frame->rs_uc.uc_stack.ss_size); 353 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); 354 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); 355 356 if (err) 357 goto give_sigsegv; 358 359 /* 360 * Arguments to signal handler: 361 * 362 * a0 = signal number 363 * a1 = 0 (should be cause) 364 * a2 = pointer to ucontext 365 * 366 * $25 and c0_epc point to the signal handler, $29 points to 367 * the struct rt_sigframe. 368 */ 369 regs->regs[ 4] = signr; 370 regs->regs[ 5] = (unsigned long) &frame->rs_info; 371 regs->regs[ 6] = (unsigned long) &frame->rs_uc; 372 regs->regs[29] = (unsigned long) frame; 373 regs->regs[31] = (unsigned long) frame->rs_code; 374 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 375 376 #if DEBUG_SIG 377 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", 378 current->comm, current->pid, 379 frame, regs->cp0_epc, regs->regs[31]); 380 #endif 381 return; 382 383 give_sigsegv: 384 force_sigsegv(signr, current); 385 } 386 387 extern void setup_rt_frame_n32(struct k_sigaction * ka, 388 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); 389 390 static inline void handle_signal(unsigned long sig, siginfo_t *info, 391 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) 392 { 393 switch(regs->regs[0]) { 394 case ERESTART_RESTARTBLOCK: 395 case ERESTARTNOHAND: 396 regs->regs[2] = EINTR; 397 break; 398 case ERESTARTSYS: 399 if(!(ka->sa.sa_flags & SA_RESTART)) { 400 regs->regs[2] = EINTR; 401 break; 402 } 403 /* fallthrough */ 404 case ERESTARTNOINTR: /* Userland will reload $v0. */ 405 regs->regs[7] = regs->regs[26]; 406 regs->cp0_epc -= 8; 407 } 408 409 regs->regs[0] = 0; /* Don't deal with this again. */ 410 411 #ifdef CONFIG_TRAD_SIGNALS 412 if (ka->sa.sa_flags & SA_SIGINFO) { 413 #else 414 if (1) { 415 #endif 416 #ifdef CONFIG_MIPS32_N32 417 if ((current->thread.mflags & MF_ABI_MASK) == MF_N32) 418 setup_rt_frame_n32 (ka, regs, sig, oldset, info); 419 else 420 #endif 421 setup_rt_frame(ka, regs, sig, oldset, info); 422 } 423 #ifdef CONFIG_TRAD_SIGNALS 424 else 425 setup_frame(ka, regs, sig, oldset); 426 #endif 427 428 if (!(ka->sa.sa_flags & SA_NODEFER)) { 429 spin_lock_irq(¤t->sighand->siglock); 430 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); 431 sigaddset(¤t->blocked,sig); 432 recalc_sigpending(); 433 spin_unlock_irq(¤t->sighand->siglock); 434 } 435 } 436 437 extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); 438 extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); 439 440 static int do_signal(sigset_t *oldset, struct pt_regs *regs) 441 { 442 struct k_sigaction ka; 443 siginfo_t info; 444 int signr; 445 446 #ifdef CONFIG_BINFMT_ELF32 447 if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) { 448 return do_signal32(oldset, regs); 449 } 450 #endif 451 452 /* 453 * We want the common case to go fast, which is why we may in certain 454 * cases get here from kernel mode. Just return without doing anything 455 * if so. 456 */ 457 if (!user_mode(regs)) 458 return 1; 459 460 if (try_to_freeze(0)) 461 goto no_signal; 462 463 if (!oldset) 464 oldset = ¤t->blocked; 465 466 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 467 if (signr > 0) { 468 handle_signal(signr, &info, &ka, oldset, regs); 469 return 1; 470 } 471 472 no_signal: 473 /* 474 * Who's code doesn't conform to the restartable syscall convention 475 * dies here!!! The li instruction, a single machine instruction, 476 * must directly be followed by the syscall instruction. 477 */ 478 if (regs->regs[0]) { 479 if (regs->regs[2] == ERESTARTNOHAND || 480 regs->regs[2] == ERESTARTSYS || 481 regs->regs[2] == ERESTARTNOINTR) { 482 regs->regs[7] = regs->regs[26]; 483 regs->cp0_epc -= 8; 484 } 485 if (regs->regs[2] == ERESTART_RESTARTBLOCK) { 486 regs->regs[2] = __NR_restart_syscall; 487 regs->regs[7] = regs->regs[26]; 488 regs->cp0_epc -= 4; 489 } 490 } 491 return 0; 492 } 493 494 /* 495 * notification of userspace execution resumption 496 * - triggered by current->work.notify_resume 497 */ 498 asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, 499 __u32 thread_info_flags) 500 { 501 /* deal with pending signal delivery */ 502 if (thread_info_flags & _TIF_SIGPENDING) { 503 #ifdef CONFIG_BINFMT_ELF32 504 if (likely((current->thread.mflags & MF_ABI_MASK) == MF_O32)) { 505 do_signal32(oldset, regs); 506 return; 507 } 508 #endif 509 #ifdef CONFIG_BINFMT_IRIX 510 if (unlikely(current->personality != PER_LINUX)) { 511 do_irix_signal(oldset, regs); 512 return; 513 } 514 #endif 515 do_signal(oldset, regs); 516 } 517 } 518