1/* 2 * Copyright (C) 2004-2006 Atmel Corporation 3 * 4 * Based on linux/arch/sh/kernel/signal.c 5 * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima 6 * Copyright (C) 1991, 1992 Linus Torvalds 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13#include <linux/sched.h> 14#include <linux/mm.h> 15#include <linux/errno.h> 16#include <linux/ptrace.h> 17#include <linux/unistd.h> 18#include <linux/tracehook.h> 19 20#include <asm/uaccess.h> 21#include <asm/ucontext.h> 22#include <asm/syscalls.h> 23 24struct rt_sigframe 25{ 26 struct siginfo info; 27 struct ucontext uc; 28 unsigned long retcode; 29}; 30 31static int 32restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 33{ 34 int err = 0; 35 36#define COPY(x) err |= __get_user(regs->x, &sc->x) 37 COPY(sr); 38 COPY(pc); 39 COPY(lr); 40 COPY(sp); 41 COPY(r12); 42 COPY(r11); 43 COPY(r10); 44 COPY(r9); 45 COPY(r8); 46 COPY(r7); 47 COPY(r6); 48 COPY(r5); 49 COPY(r4); 50 COPY(r3); 51 COPY(r2); 52 COPY(r1); 53 COPY(r0); 54#undef COPY 55 56 /* 57 * Don't allow anyone to pretend they're running in supervisor 58 * mode or something... 59 */ 60 err |= !valid_user_regs(regs); 61 62 return err; 63} 64 65 66asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) 67{ 68 struct rt_sigframe __user *frame; 69 sigset_t set; 70 71 /* Always make any pending restarted system calls return -EINTR */ 72 current->restart_block.fn = do_no_restart_syscall; 73 74 frame = (struct rt_sigframe __user *)regs->sp; 75 pr_debug("SIG return: frame = %p\n", frame); 76 77 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 78 goto badframe; 79 80 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 81 goto badframe; 82 83 set_current_blocked(&set); 84 85 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 86 goto badframe; 87 88 if (restore_altstack(&frame->uc.uc_stack)) 89 goto badframe; 90 91 pr_debug("Context restored: pc = %08lx, lr = %08lx, sp = %08lx\n", 92 regs->pc, regs->lr, regs->sp); 93 94 return regs->r12; 95 96badframe: 97 force_sig(SIGSEGV, current); 98 return 0; 99} 100 101static int 102setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) 103{ 104 int err = 0; 105 106#define COPY(x) err |= __put_user(regs->x, &sc->x) 107 COPY(sr); 108 COPY(pc); 109 COPY(lr); 110 COPY(sp); 111 COPY(r12); 112 COPY(r11); 113 COPY(r10); 114 COPY(r9); 115 COPY(r8); 116 COPY(r7); 117 COPY(r6); 118 COPY(r5); 119 COPY(r4); 120 COPY(r3); 121 COPY(r2); 122 COPY(r1); 123 COPY(r0); 124#undef COPY 125 126 return err; 127} 128 129static inline void __user * 130get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize) 131{ 132 unsigned long sp = sigsp(regs->sp, ksig); 133 134 return (void __user *)((sp - framesize) & ~3); 135} 136 137static int 138setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) 139{ 140 struct rt_sigframe __user *frame; 141 int err = 0; 142 143 frame = get_sigframe(ksig, regs, sizeof(*frame)); 144 err = -EFAULT; 145 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 146 goto out; 147 148 /* 149 * Set up the return code: 150 * 151 * mov r8, __NR_rt_sigreturn 152 * scall 153 * 154 * Note: This will blow up since we're using a non-executable 155 * stack. Better use SA_RESTORER. 156 */ 157#if __NR_rt_sigreturn > 127 158# error __NR_rt_sigreturn must be < 127 to fit in a short mov 159#endif 160 err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20), 161 &frame->retcode); 162 163 err |= copy_siginfo_to_user(&frame->info, &ksig->info); 164 165 /* Set up the ucontext */ 166 err |= __put_user(0, &frame->uc.uc_flags); 167 err |= __put_user(NULL, &frame->uc.uc_link); 168 err |= __save_altstack(&frame->uc.uc_stack, regs->sp); 169 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); 170 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 171 172 if (err) 173 goto out; 174 175 regs->r12 = ksig->sig; 176 regs->r11 = (unsigned long) &frame->info; 177 regs->r10 = (unsigned long) &frame->uc; 178 regs->sp = (unsigned long) frame; 179 if (ksig->ka.sa.sa_flags & SA_RESTORER) 180 regs->lr = (unsigned long)ksig->ka.sa.sa_restorer; 181 else { 182 printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n", 183 current->comm, current->pid); 184 regs->lr = (unsigned long) &frame->retcode; 185 } 186 187 pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n", 188 current->comm, current->pid, ksig->sig, regs->sp, 189 regs->pc, ksig->ka.sa.sa_handler, regs->lr); 190 191 regs->pc = (unsigned long)ksig->ka.sa.sa_handler; 192 193out: 194 return err; 195} 196 197static inline void setup_syscall_restart(struct pt_regs *regs) 198{ 199 if (regs->r12 == -ERESTART_RESTARTBLOCK) 200 regs->r8 = __NR_restart_syscall; 201 else 202 regs->r12 = regs->r12_orig; 203 regs->pc -= 2; 204} 205 206static inline void 207handle_signal(struct ksignal *ksig, struct pt_regs *regs, int syscall) 208{ 209 int ret; 210 211 /* 212 * Set up the stack frame 213 */ 214 ret = setup_rt_frame(ksig, sigmask_to_save(), regs); 215 216 /* 217 * Check that the resulting registers are sane 218 */ 219 ret |= !valid_user_regs(regs); 220 221 /* 222 * Block the signal if we were successful. 223 */ 224 signal_setup_done(ret, ksig, 0); 225} 226 227/* 228 * Note that 'init' is a special process: it doesn't get signals it 229 * doesn't want to handle. Thus you cannot kill init even with a 230 * SIGKILL even by mistake. 231 */ 232static void do_signal(struct pt_regs *regs, int syscall) 233{ 234 struct ksignal ksig; 235 236 /* 237 * We want the common case to go fast, which is why we may in 238 * certain cases get here from kernel mode. Just return 239 * without doing anything if so. 240 */ 241 if (!user_mode(regs)) 242 return; 243 244 get_signal(&ksig); 245 if (syscall) { 246 switch (regs->r12) { 247 case -ERESTART_RESTARTBLOCK: 248 case -ERESTARTNOHAND: 249 if (ksig.sig > 0) { 250 regs->r12 = -EINTR; 251 break; 252 } 253 /* fall through */ 254 case -ERESTARTSYS: 255 if (ksig.sig > 0 && !(ksig.ka.sa.sa_flags & SA_RESTART)) { 256 regs->r12 = -EINTR; 257 break; 258 } 259 /* fall through */ 260 case -ERESTARTNOINTR: 261 setup_syscall_restart(regs); 262 } 263 } 264 265 if (!ksig.sig) { 266 /* No signal to deliver -- put the saved sigmask back */ 267 restore_saved_sigmask(); 268 return; 269 } 270 271 handle_signal(&ksig, regs, syscall); 272} 273 274asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) 275{ 276 int syscall = 0; 277 278 if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR) 279 syscall = 1; 280 281 if (ti->flags & _TIF_SIGPENDING) 282 do_signal(regs, syscall); 283 284 if (ti->flags & _TIF_NOTIFY_RESUME) { 285 clear_thread_flag(TIF_NOTIFY_RESUME); 286 tracehook_notify_resume(regs); 287 } 288} 289