1/* 2 * arch/ubicom32/kernel/signal.c 3 * Ubicom32 architecture signal handling implementation. 4 * 5 * (C) Copyright 2009, Ubicom, Inc. 6 * Copyright (C) 1991, 1992 Linus Torvalds 7 * Linux/m68k support by Hamish Macdonald 8 * 68060 fixes by Jesper Skov 9 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab 10 * mathemu support by Roman Zippel 11 * ++roman (07/09/96): implemented signal stacks 12 * 13 * This file is part of the Ubicom32 Linux Kernel Port. 14 * 15 * The Ubicom32 Linux Kernel Port is free software: you can redistribute 16 * it and/or modify it under the terms of the GNU General Public License 17 * as published by the Free Software Foundation, either version 2 of the 18 * License, or (at your option) any later version. 19 * 20 * The Ubicom32 Linux Kernel Port is distributed in the hope that it 21 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 22 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 23 * the GNU General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with the Ubicom32 Linux Kernel Port. If not, 27 * see <http://www.gnu.org/licenses/>. 28 * 29 * Ubicom32 implementation derived from (with many thanks): 30 * arch/m68knommu 31 * arch/blackfin 32 * arch/parisc 33 * 34 * mathemu support by Roman Zippel 35 * (Note: fpstate in the signal context is completely ignored for the emulator 36 * and the internal floating point format is put on stack) 37 * 38 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 39 * Atari :-) Current limitation: Only one sigstack can be active at one time. 40 * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 41 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 42 * signal handlers! 43 */ 44 45#include <linux/module.h> 46#include <linux/sched.h> 47#include <linux/mm.h> 48#include <linux/kernel.h> 49#include <linux/signal.h> 50#include <linux/syscalls.h> 51#include <linux/errno.h> 52#include <linux/wait.h> 53#include <linux/ptrace.h> 54#include <linux/unistd.h> 55#include <linux/stddef.h> 56#include <linux/highuid.h> 57#include <linux/tty.h> 58#include <linux/personality.h> 59#include <linux/binfmts.h> 60 61#include <asm/setup.h> 62#include <asm/uaccess.h> 63#include <asm/pgtable.h> 64#include <asm/traps.h> 65#include <asm/ucontext.h> 66 67#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 68 69/* 70 * asm signal return handlers. 71 */ 72void ret_from_user_signal(void); 73void ret_from_user_rt_signal(void); 74asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); 75 76/* 77 * Common signal suspend implementation 78 */ 79static int signal_suspend(sigset_t *saveset, struct pt_regs *regs) 80{ 81 regs->dn[0] = -EINTR; 82 while (1) { 83 current->state = TASK_INTERRUPTIBLE; 84 schedule(); 85 if (!do_signal(saveset, regs)) { 86 continue; 87 } 88 /* 89 * If the current frame type is a signal trampoline we are 90 * actually going to call the signal handler so we return the 91 * desired d0 as the return value. 92 */ 93 if (regs->frame_type == UBICOM32_FRAME_TYPE_SIGTRAMP) { 94 return regs->dn[0]; 95 } 96 return -EINTR; 97 } 98 /* 99 * Should never get here 100 */ 101 BUG(); 102 return 0; 103} 104 105/* 106 * Atomically swap in the new signal mask, and wait for a signal. 107 */ 108asmlinkage int do_sigsuspend(struct pt_regs *regs) 109{ 110 old_sigset_t mask = regs->dn[0]; 111 sigset_t saveset; 112 113 mask &= _BLOCKABLE; 114 spin_lock_irq(¤t->sighand->siglock); 115 saveset = current->blocked; 116 siginitset(¤t->blocked, mask); 117 recalc_sigpending(); 118 spin_unlock_irq(¤t->sighand->siglock); 119 120 /* 121 * Call common handler 122 */ 123 return signal_suspend(&saveset, regs); 124} 125 126asmlinkage int 127do_rt_sigsuspend(struct pt_regs *regs) 128{ 129 sigset_t *unewset = (sigset_t *)regs->dn[0]; 130 size_t sigsetsize = (size_t)regs->dn[1]; 131 sigset_t saveset, newset; 132 133 /* XXX: Don't preclude handling different sized sigset_t's. */ 134 if (sigsetsize != sizeof(sigset_t)) 135 return -EINVAL; 136 137 if (copy_from_user(&newset, unewset, sizeof(newset))) 138 return -EFAULT; 139 sigdelsetmask(&newset, ~_BLOCKABLE); 140 141 spin_lock_irq(¤t->sighand->siglock); 142 saveset = current->blocked; 143 current->blocked = newset; 144 recalc_sigpending(); 145 spin_unlock_irq(¤t->sighand->siglock); 146 147 /* 148 * Call common handler 149 */ 150 return signal_suspend(&saveset, regs); 151} 152 153asmlinkage int 154sys_sigaction(int sig, const struct old_sigaction *act, 155 struct old_sigaction *oact) 156{ 157 struct k_sigaction new_ka, old_ka; 158 int ret; 159 160 if (act) { 161 old_sigset_t mask; 162 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 163 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 164 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 165 return -EFAULT; 166 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 167 __get_user(mask, &act->sa_mask); 168 siginitset(&new_ka.sa.sa_mask, mask); 169 } 170 171 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 172 173 if (!ret && oact) { 174 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 175 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 176 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 177 return -EFAULT; 178 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 179 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 180 } 181 182 return ret; 183} 184 185asmlinkage int 186do_sys_sigaltstack(struct pt_regs *regs) 187{ 188 const stack_t *uss = (stack_t *) regs->dn[0]; 189 stack_t *uoss = (stack_t *)regs->dn[1]; 190 return do_sigaltstack(uss, uoss, regs->an[7]); 191} 192 193/* 194 * fdpic_func_descriptor describes sa_handler when the application is FDPIC 195 */ 196struct fdpic_func_descriptor { 197 unsigned long text; 198 unsigned long GOT; 199}; 200 201/* 202 * rt_sigframe is stored on the user stack immediately before (above) 203 * the signal handlers stack. 204 */ 205struct rt_sigframe 206{ 207 unsigned long syscall_number; /* This holds __NR_rt_sigreturn. */ 208 unsigned long restore_all_regs; /* This field gets set to 1 if the frame 209 * type is TRAP or INTERRUPT. */ 210 siginfo_t *info; 211 struct ucontext uc; 212 int sig; 213 void *pretcode; 214}; 215 216/* 217 * Do a signal return; undo the signal stack. 218 */ 219asmlinkage int do_sigreturn(unsigned long __unused) 220{ 221 BUG(); 222 return 0; 223} 224 225asmlinkage int do_rt_sigreturn(struct pt_regs *regs) 226{ 227 unsigned long usp = regs->an[7]; 228 struct rt_sigframe *frame = (struct rt_sigframe *)(usp); 229 sigset_t set; 230 231 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 232 goto badframe; 233 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 234 goto badframe; 235 236 sigdelsetmask(&set, ~_BLOCKABLE); 237 spin_lock_irq(¤t->sighand->siglock); 238 current->blocked = set; 239 recalc_sigpending(); 240 spin_unlock_irq(¤t->sighand->siglock); 241 242 if (copy_from_user(regs, &frame->uc.uc_mcontext, sizeof(struct pt_regs))) 243 goto badframe; 244 return regs->dn[0]; 245 246badframe: 247 force_sig(SIGSEGV, current); 248 return 0; 249} 250 251static inline void * 252get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 253{ 254 unsigned long usp; 255 256 /* Default to using normal stack. */ 257 usp = regs->an[7]; 258 259 /* This is the X/Open sanctioned signal stack switching. */ 260 if (ka->sa.sa_flags & SA_ONSTACK) { 261 if (!sas_ss_flags(usp)) 262 usp = current->sas_ss_sp + current->sas_ss_size; 263 } 264 return (void *)((usp - frame_size) & ~0x3); 265} 266 267/* 268 * signal_trampoline: Defined in ubicom32_syscall.S 269 */ 270asmlinkage void signal_trampoline(void)__attribute__((naked)); 271 272static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 273 sigset_t *set, struct pt_regs *regs) 274{ 275 struct rt_sigframe *frame; 276 int err = 0; 277 278 frame = (struct rt_sigframe *) get_sigframe(ka, regs, sizeof(*frame)); 279 280 /* 281 * The 'err |=' have been may criticized as bad code style, but I 282 * strongly suspect that we want this code to be fast. So for 283 * now it stays as is. 284 */ 285 err |= __put_user( ( (current_thread_info()->exec_domain) 286 && (current_thread_info()->exec_domain->signal_invmap) 287 && (sig < 32) ) 288 ? current_thread_info()->exec_domain->signal_invmap[sig] 289 : sig, &frame->sig); 290 err |= __put_user(info, &frame->info); 291 292 /* Create the ucontext. */ 293 err |= __put_user(0, &frame->uc.uc_flags); 294 err |= __put_user(0, &frame->uc.uc_link); 295 err |= __put_user((void *)current->sas_ss_sp, 296 &frame->uc.uc_stack.ss_sp); 297 err |= __put_user(sas_ss_flags(regs->an[7]), 298 &frame->uc.uc_stack.ss_flags); 299 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 300 err |= __put_user(__NR_rt_sigreturn, &frame->syscall_number); 301 if ((regs->frame_type == UBICOM32_FRAME_TYPE_TRAP) || 302 (regs->frame_type == UBICOM32_FRAME_TYPE_INTERRUPT)) { 303 err |= __put_user(1, &frame->restore_all_regs); 304 } else { 305 err |= __put_user(0, &frame->restore_all_regs); 306 } 307 err |= copy_to_user (&frame->uc.uc_mcontext.sc_regs, regs, sizeof(struct pt_regs)); 308 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 309 310 if (err) 311 goto give_sigsegv; 312 313 /* 314 * Set up registers for signal handler NOTE: Do not modify dn[14], it 315 * contains the userspace tls pointer, so it important that it carries 316 * over to the signal handler. 317 */ 318 regs->an[7] = (unsigned long)frame; 319 regs->pc = (unsigned long) signal_trampoline; 320 regs->an[5] = (unsigned long) signal_trampoline; 321 regs->dn[0] = sig; 322 regs->dn[1] = (unsigned long) frame->info; 323 regs->dn[2] = (unsigned int) &frame->uc; 324 325 /* 326 * If this is FDPIC then the signal handler is actually a function 327 * descriptor. 328 */ 329 if (current->personality & FDPIC_FUNCPTRS) { 330 struct fdpic_func_descriptor __user *funcptr = 331 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 332 err |= __get_user(regs->dn[3], &funcptr->text); 333 err |= __get_user(regs->an[0], &funcptr->GOT); 334 if (err) 335 goto give_sigsegv; 336 337 /* 338 * The funcdesc must be in a3 as this is required for the lazy 339 * resolver in ld.so, if the application is not FDPIC a3 is not 340 * used. 341 */ 342 regs->an[3] = (unsigned long) funcptr; 343 344 } else { 345 regs->dn[3] = (unsigned long)ka->sa.sa_handler; 346 regs->an[0] = 0; 347 } 348 349 regs->frame_type = UBICOM32_FRAME_TYPE_SIGTRAMP; 350 351 return; 352 353give_sigsegv: 354 /* user space exception */ 355 force_sigsegv(sig, current); 356} 357 358static inline void 359handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) 360{ 361 switch (regs->dn[0]) { 362 case -ERESTARTNOHAND: 363 if (!has_handler) 364 goto do_restart; 365 regs->dn[0] = -EINTR; 366 break; 367 368 case -ERESTARTSYS: 369 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { 370 regs->dn[0] = -EINTR; 371 break; 372 } 373 /* fallthrough */ 374 case -ERESTARTNOINTR: 375 do_restart: 376 regs->dn[0] = regs->original_dn_0; 377 regs->pc -= 8; 378 regs->an[5] -= 8; 379 break; 380 } 381} 382 383/* 384 * OK, we're invoking a handler 385 */ 386static void 387handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 388 sigset_t *oldset, struct pt_regs *regs) 389{ 390 /* are we from a system call? */ 391 if (regs->frame_type == -1) 392 /* If so, check system call restarting.. */ 393 handle_restart(regs, ka, 1); 394 395 /* set up the stack frame */ 396 setup_rt_frame(sig, ka, info, oldset, regs); 397 398 if (ka->sa.sa_flags & SA_ONESHOT) 399 ka->sa.sa_handler = SIG_DFL; 400 401 spin_lock_irq(¤t->sighand->siglock); 402 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); 403 if (!(ka->sa.sa_flags & SA_NODEFER)) 404 sigaddset(¤t->blocked,sig); 405 recalc_sigpending(); 406 spin_unlock_irq(¤t->sighand->siglock); 407} 408 409/* 410 * Note that 'init' is a special process: it doesn't get signals it doesn't 411 * want to handle. Thus you cannot kill init even with a SIGKILL even by 412 * mistake. 413 */ 414asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) 415{ 416 struct k_sigaction ka; 417 siginfo_t info; 418 int signr; 419 420 /* 421 * We want the common case to go fast, which 422 * is why we may in certain cases get here from 423 * kernel mode. Just return without doing anything 424 * if so. 425 */ 426 if (!user_mode(regs)) 427 return 1; 428 429 if (!oldset) 430 oldset = ¤t->blocked; 431 432 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 433 if (signr > 0) { 434 /* Whee! Actually deliver the signal. */ 435 handle_signal(signr, &ka, &info, oldset, regs); 436 return 1; 437 } 438 439 /* Did we come from a system call? */ 440 if (regs->frame_type == -1) { 441 /* Restart the system call - no handlers present */ 442 handle_restart(regs, NULL, 0); 443 } 444 445 return 0; 446} 447 448/* 449 * sys_sigreturn() 450 * Return handler for signal clean-up. 451 * 452 * NOTE: Ubicom32 does not use this syscall. Instead we rely 453 * on do_rt_sigreturn(). 454 */ 455asmlinkage long sys_sigreturn(void) 456{ 457 return -ENOSYS; 458} 459