1/* 2 * arch/score/kernel/signal.c 3 * 4 * Score Processor version. 5 * 6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd. 7 * Chen Liqin <liqin.chen@sunplusct.com> 8 * Lennox Wu <lennox.wu@sunplusct.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, see the file COPYING, or write 22 * to the Free Software Foundation, Inc., 23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 */ 25 26#include <linux/errno.h> 27#include <linux/signal.h> 28#include <linux/ptrace.h> 29#include <linux/unistd.h> 30#include <linux/uaccess.h> 31 32#include <asm/cacheflush.h> 33#include <asm/syscalls.h> 34#include <asm/ucontext.h> 35 36#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 37 38struct rt_sigframe { 39 u32 rs_ass[4]; /* argument save space */ 40 u32 rs_code[2]; /* signal trampoline */ 41 struct siginfo rs_info; 42 struct ucontext rs_uc; 43}; 44 45static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 46{ 47 int err = 0; 48 unsigned long reg; 49 50 reg = regs->cp0_epc; err |= __put_user(reg, &sc->sc_pc); 51 err |= __put_user(regs->cp0_psr, &sc->sc_psr); 52 err |= __put_user(regs->cp0_condition, &sc->sc_condition); 53 54 55#define save_gp_reg(i) { \ 56 reg = regs->regs[i]; \ 57 err |= __put_user(reg, &sc->sc_regs[i]); \ 58} while (0) 59 save_gp_reg(0); save_gp_reg(1); save_gp_reg(2); 60 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); 61 save_gp_reg(6); save_gp_reg(7); save_gp_reg(8); 62 save_gp_reg(9); save_gp_reg(10); save_gp_reg(11); 63 save_gp_reg(12); save_gp_reg(13); save_gp_reg(14); 64 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); 65 save_gp_reg(18); save_gp_reg(19); save_gp_reg(20); 66 save_gp_reg(21); save_gp_reg(22); save_gp_reg(23); 67 save_gp_reg(24); save_gp_reg(25); save_gp_reg(26); 68 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); 69#undef save_gp_reg 70 71 reg = regs->ceh; err |= __put_user(reg, &sc->sc_mdceh); 72 reg = regs->cel; err |= __put_user(reg, &sc->sc_mdcel); 73 err |= __put_user(regs->cp0_ecr, &sc->sc_ecr); 74 err |= __put_user(regs->cp0_ema, &sc->sc_ema); 75 76 return err; 77} 78 79static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 80{ 81 int err = 0; 82 u32 reg; 83 84 err |= __get_user(regs->cp0_epc, &sc->sc_pc); 85 err |= __get_user(regs->cp0_condition, &sc->sc_condition); 86 87 err |= __get_user(reg, &sc->sc_mdceh); 88 regs->ceh = (int) reg; 89 err |= __get_user(reg, &sc->sc_mdcel); 90 regs->cel = (int) reg; 91 92 err |= __get_user(reg, &sc->sc_psr); 93 regs->cp0_psr = (int) reg; 94 err |= __get_user(reg, &sc->sc_ecr); 95 regs->cp0_ecr = (int) reg; 96 err |= __get_user(reg, &sc->sc_ema); 97 regs->cp0_ema = (int) reg; 98 99#define restore_gp_reg(i) do { \ 100 err |= __get_user(reg, &sc->sc_regs[i]); \ 101 regs->regs[i] = reg; \ 102} while (0) 103 restore_gp_reg(0); restore_gp_reg(1); restore_gp_reg(2); 104 restore_gp_reg(3); restore_gp_reg(4); restore_gp_reg(5); 105 restore_gp_reg(6); restore_gp_reg(7); restore_gp_reg(8); 106 restore_gp_reg(9); restore_gp_reg(10); restore_gp_reg(11); 107 restore_gp_reg(12); restore_gp_reg(13); restore_gp_reg(14); 108 restore_gp_reg(15); restore_gp_reg(16); restore_gp_reg(17); 109 restore_gp_reg(18); restore_gp_reg(19); restore_gp_reg(20); 110 restore_gp_reg(21); restore_gp_reg(22); restore_gp_reg(23); 111 restore_gp_reg(24); restore_gp_reg(25); restore_gp_reg(26); 112 restore_gp_reg(27); restore_gp_reg(28); restore_gp_reg(29); 113#undef restore_gp_reg 114 115 return err; 116} 117 118/* 119 * Determine which stack to use.. 120 */ 121static void __user *get_sigframe(struct k_sigaction *ka, 122 struct pt_regs *regs, size_t frame_size) 123{ 124 unsigned long sp; 125 126 /* Default to using normal stack */ 127 sp = regs->regs[0]; 128 sp -= 32; 129 130 /* This is the X/Open sanctioned signal stack switching. */ 131 if ((ka->sa.sa_flags & SA_ONSTACK) && (!on_sig_stack(sp))) 132 sp = current->sas_ss_sp + current->sas_ss_size; 133 134 return (void __user*)((sp - frame_size) & ~7); 135} 136 137asmlinkage long 138score_sigaltstack(struct pt_regs *regs) 139{ 140 const stack_t __user *uss = (const stack_t __user *) regs->regs[4]; 141 stack_t __user *uoss = (stack_t __user *) regs->regs[5]; 142 unsigned long usp = regs->regs[0]; 143 144 return do_sigaltstack(uss, uoss, usp); 145} 146 147asmlinkage long 148score_rt_sigreturn(struct pt_regs *regs) 149{ 150 struct rt_sigframe __user *frame; 151 sigset_t set; 152 stack_t st; 153 int sig; 154 155 frame = (struct rt_sigframe __user *) regs->regs[0]; 156 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 157 goto badframe; 158 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) 159 goto badframe; 160 161 sigdelsetmask(&set, ~_BLOCKABLE); 162 spin_lock_irq(¤t->sighand->siglock); 163 current->blocked = set; 164 recalc_sigpending(); 165 spin_unlock_irq(¤t->sighand->siglock); 166 167 sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext); 168 if (sig < 0) 169 goto badframe; 170 else if (sig) 171 force_sig(sig, current); 172 173 if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) 174 goto badframe; 175 176 /* It is more difficult to avoid calling this function than to 177 call it and ignore errors. */ 178 do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]); 179 180 __asm__ __volatile__( 181 "mv\tr0, %0\n\t" 182 "la\tr8, syscall_exit\n\t" 183 "br\tr8\n\t" 184 : : "r" (regs) : "r8"); 185 186badframe: 187 force_sig(SIGSEGV, current); 188 189 return 0; 190} 191 192static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, 193 int signr, sigset_t *set, siginfo_t *info) 194{ 195 struct rt_sigframe __user *frame; 196 int err = 0; 197 198 frame = get_sigframe(ka, regs, sizeof(*frame)); 199 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 200 goto give_sigsegv; 201 202 /* 203 * Set up the return code ... 204 * 205 * li v0, __NR_rt_sigreturn 206 * syscall 207 */ 208 err |= __put_user(0x87788000 + __NR_rt_sigreturn*2, 209 frame->rs_code + 0); 210 err |= __put_user(0x80008002, frame->rs_code + 1); 211 flush_cache_sigtramp((unsigned long) frame->rs_code); 212 213 err |= copy_siginfo_to_user(&frame->rs_info, info); 214 err |= __put_user(0, &frame->rs_uc.uc_flags); 215 err |= __put_user(NULL, &frame->rs_uc.uc_link); 216 err |= __put_user((void __user *)current->sas_ss_sp, 217 &frame->rs_uc.uc_stack.ss_sp); 218 err |= __put_user(sas_ss_flags(regs->regs[0]), 219 &frame->rs_uc.uc_stack.ss_flags); 220 err |= __put_user(current->sas_ss_size, 221 &frame->rs_uc.uc_stack.ss_size); 222 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); 223 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); 224 225 if (err) 226 goto give_sigsegv; 227 228 regs->regs[0] = (unsigned long) frame; 229 regs->regs[3] = (unsigned long) frame->rs_code; 230 regs->regs[4] = signr; 231 regs->regs[5] = (unsigned long) &frame->rs_info; 232 regs->regs[6] = (unsigned long) &frame->rs_uc; 233 regs->regs[29] = (unsigned long) ka->sa.sa_handler; 234 regs->cp0_epc = (unsigned long) ka->sa.sa_handler; 235 236 return 0; 237 238give_sigsegv: 239 if (signr == SIGSEGV) 240 ka->sa.sa_handler = SIG_DFL; 241 force_sig(SIGSEGV, current); 242 return -EFAULT; 243} 244 245static int handle_signal(unsigned long sig, siginfo_t *info, 246 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) 247{ 248 int ret; 249 250 if (regs->is_syscall) { 251 switch (regs->regs[4]) { 252 case ERESTART_RESTARTBLOCK: 253 case ERESTARTNOHAND: 254 regs->regs[4] = EINTR; 255 break; 256 case ERESTARTSYS: 257 if (!(ka->sa.sa_flags & SA_RESTART)) { 258 regs->regs[4] = EINTR; 259 break; 260 } 261 case ERESTARTNOINTR: 262 regs->regs[4] = regs->orig_r4; 263 regs->regs[7] = regs->orig_r7; 264 regs->cp0_epc -= 8; 265 } 266 267 regs->is_syscall = 0; 268 } 269 270 /* 271 * Set up the stack frame 272 */ 273 ret = setup_rt_frame(ka, regs, sig, oldset, info); 274 275 spin_lock_irq(¤t->sighand->siglock); 276 sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); 277 if (!(ka->sa.sa_flags & SA_NODEFER)) 278 sigaddset(¤t->blocked, sig); 279 recalc_sigpending(); 280 spin_unlock_irq(¤t->sighand->siglock); 281 282 return ret; 283} 284 285static void do_signal(struct pt_regs *regs) 286{ 287 struct k_sigaction ka; 288 sigset_t *oldset; 289 siginfo_t info; 290 int signr; 291 292 /* 293 * We want the common case to go fast, which is why we may in certain 294 * cases get here from kernel mode. Just return without doing anything 295 * if so. 296 */ 297 if (!user_mode(regs)) 298 return; 299 300 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 301 oldset = ¤t->saved_sigmask; 302 else 303 oldset = ¤t->blocked; 304 305 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 306 if (signr > 0) { 307 /* Actually deliver the signal. */ 308 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 309 /* 310 * A signal was successfully delivered; the saved 311 * sigmask will have been stored in the signal frame, 312 * and will be restored by sigreturn, so we can simply 313 * clear the TIF_RESTORE_SIGMASK flag. 314 */ 315 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 316 clear_thread_flag(TIF_RESTORE_SIGMASK); 317 } 318 319 return; 320 } 321 322 if (regs->is_syscall) { 323 if (regs->regs[4] == ERESTARTNOHAND || 324 regs->regs[4] == ERESTARTSYS || 325 regs->regs[4] == ERESTARTNOINTR) { 326 regs->regs[4] = regs->orig_r4; 327 regs->regs[7] = regs->orig_r7; 328 regs->cp0_epc -= 8; 329 } 330 331 if (regs->regs[4] == ERESTART_RESTARTBLOCK) { 332 regs->regs[27] = __NR_restart_syscall; 333 regs->regs[4] = regs->orig_r4; 334 regs->regs[7] = regs->orig_r7; 335 regs->cp0_epc -= 8; 336 } 337 338 regs->is_syscall = 0; /* Don't deal with this again. */ 339 } 340 341 /* 342 * If there's no signal to deliver, we just put the saved sigmask 343 * back 344 */ 345 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 346 clear_thread_flag(TIF_RESTORE_SIGMASK); 347 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); 348 } 349} 350 351/* 352 * notification of userspace execution resumption 353 * - triggered by the TIF_WORK_MASK flags 354 */ 355asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, 356 __u32 thread_info_flags) 357{ 358 /* deal with pending signal delivery */ 359 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 360 do_signal(regs); 361} 362