1 /* 2 * linux/arch/h8300/kernel/signal.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive 8 * for more details. 9 */ 10 11 /* 12 * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp> 13 * and David McCullough <davidm@snapgear.com> 14 * 15 * Based on 16 * Linux/m68k by Hamish Macdonald 17 */ 18 19 /* 20 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 21 * Atari :-) Current limitation: Only one sigstack can be active at one time. 22 * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 23 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 24 * signal handlers! 25 */ 26 27 #include <linux/sched.h> 28 #include <linux/mm.h> 29 #include <linux/kernel.h> 30 #include <linux/signal.h> 31 #include <linux/syscalls.h> 32 #include <linux/errno.h> 33 #include <linux/wait.h> 34 #include <linux/ptrace.h> 35 #include <linux/unistd.h> 36 #include <linux/stddef.h> 37 #include <linux/highuid.h> 38 #include <linux/personality.h> 39 #include <linux/tty.h> 40 #include <linux/binfmts.h> 41 #include <linux/tracehook.h> 42 43 #include <asm/setup.h> 44 #include <asm/uaccess.h> 45 #include <asm/pgtable.h> 46 #include <asm/traps.h> 47 #include <asm/ucontext.h> 48 49 /* 50 * Do a signal return; undo the signal stack. 51 * 52 * Keep the return code on the stack quadword aligned! 53 * That makes the cache flush below easier. 54 */ 55 56 struct rt_sigframe { 57 long dummy_er0; 58 long dummy_vector; 59 #if defined(CONFIG_CPU_H8S) 60 short dummy_exr; 61 #endif 62 long dummy_pc; 63 char *pretcode; 64 struct siginfo *pinfo; 65 void *puc; 66 unsigned char retcode[8]; 67 struct siginfo info; 68 struct ucontext uc; 69 int sig; 70 } __packed __aligned(2); 71 72 static inline int restore_sigcontext(struct sigcontext * usc,int * pd0)73 restore_sigcontext(struct sigcontext *usc, int *pd0) 74 { 75 struct pt_regs *regs = current_pt_regs(); 76 int err = 0; 77 unsigned int ccr; 78 unsigned int usp; 79 unsigned int er0; 80 81 /* Always make any pending restarted system calls return -EINTR */ 82 current->restart_block.fn = do_no_restart_syscall; 83 84 /* restore passed registers */ 85 #define COPY(r) do { err |= get_user(regs->r, &usc->sc_##r); } while (0) 86 COPY(er1); 87 COPY(er2); 88 COPY(er3); 89 COPY(er5); 90 COPY(pc); 91 ccr = regs->ccr & 0x10; 92 COPY(ccr); 93 #undef COPY 94 regs->ccr &= 0xef; 95 regs->ccr |= ccr; 96 regs->orig_er0 = -1; /* disable syscall checks */ 97 err |= __get_user(usp, &usc->sc_usp); 98 regs->sp = usp; 99 100 err |= __get_user(er0, &usc->sc_er0); 101 *pd0 = er0; 102 return err; 103 } 104 sys_rt_sigreturn(void)105 asmlinkage int sys_rt_sigreturn(void) 106 { 107 unsigned long usp = rdusp(); 108 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); 109 sigset_t set; 110 int er0; 111 112 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 113 goto badframe; 114 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 115 goto badframe; 116 117 set_current_blocked(&set); 118 119 if (restore_sigcontext(&frame->uc.uc_mcontext, &er0)) 120 goto badframe; 121 122 if (restore_altstack(&frame->uc.uc_stack)) 123 goto badframe; 124 125 return er0; 126 127 badframe: 128 force_sig(SIGSEGV, current); 129 return 0; 130 } 131 setup_sigcontext(struct sigcontext __user * sc,struct pt_regs * regs,unsigned long mask)132 static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 133 unsigned long mask) 134 { 135 int err = 0; 136 137 err |= __put_user(regs->er0, &sc->sc_er0); 138 err |= __put_user(regs->er1, &sc->sc_er1); 139 err |= __put_user(regs->er2, &sc->sc_er2); 140 err |= __put_user(regs->er3, &sc->sc_er3); 141 err |= __put_user(regs->er4, &sc->sc_er4); 142 err |= __put_user(regs->er5, &sc->sc_er5); 143 err |= __put_user(regs->er6, &sc->sc_er6); 144 err |= __put_user(rdusp(), &sc->sc_usp); 145 err |= __put_user(regs->pc, &sc->sc_pc); 146 err |= __put_user(regs->ccr, &sc->sc_ccr); 147 err |= __put_user(mask, &sc->sc_mask); 148 149 return err; 150 } 151 152 static inline void __user * get_sigframe(struct ksignal * ksig,struct pt_regs * regs,size_t frame_size)153 get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size) 154 { 155 return (void __user *)((sigsp(rdusp(), ksig) - frame_size) & -8UL); 156 } 157 setup_rt_frame(struct ksignal * ksig,sigset_t * set,struct pt_regs * regs)158 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, 159 struct pt_regs *regs) 160 { 161 struct rt_sigframe *frame; 162 int err = 0; 163 unsigned char *ret; 164 165 frame = get_sigframe(ksig, regs, sizeof(*frame)); 166 167 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 168 return -EFAULT; 169 170 if (ksig->ka.sa.sa_flags & SA_SIGINFO) 171 err |= copy_siginfo_to_user(&frame->info, &ksig->info); 172 173 /* Create the ucontext. */ 174 err |= __put_user(0, &frame->uc.uc_flags); 175 err |= __put_user(0, &frame->uc.uc_link); 176 err |= __save_altstack(&frame->uc.uc_stack, rdusp()); 177 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); 178 err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 179 if (err) 180 return -EFAULT; 181 182 /* Set up to return from userspace. */ 183 ret = (unsigned char *)&frame->retcode; 184 if (ksig->ka.sa.sa_flags & SA_RESTORER) 185 ret = (unsigned char *)(ksig->ka.sa.sa_restorer); 186 else { 187 /* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */ 188 err |= __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff), 189 (unsigned long *)(frame->retcode + 0)); 190 err |= __put_user(0x5700, 191 (unsigned short *)(frame->retcode + 4)); 192 } 193 err |= __put_user(ret, &frame->pretcode); 194 195 if (err) 196 return -EFAULT; 197 198 /* Set up registers for signal handler */ 199 regs->sp = (unsigned long)frame; 200 regs->pc = (unsigned long)ksig->ka.sa.sa_handler; 201 regs->er0 = ksig->sig; 202 regs->er1 = (unsigned long)&(frame->info); 203 regs->er2 = (unsigned long)&frame->uc; 204 regs->er5 = current->mm->start_data; /* GOT base */ 205 206 return 0; 207 } 208 209 static void handle_restart(struct pt_regs * regs,struct k_sigaction * ka)210 handle_restart(struct pt_regs *regs, struct k_sigaction *ka) 211 { 212 switch (regs->er0) { 213 case -ERESTARTNOHAND: 214 if (!ka) 215 goto do_restart; 216 regs->er0 = -EINTR; 217 break; 218 case -ERESTART_RESTARTBLOCK: 219 if (!ka) { 220 regs->er0 = __NR_restart_syscall; 221 regs->pc -= 2; 222 } else 223 regs->er0 = -EINTR; 224 break; 225 case -ERESTARTSYS: 226 if (!(ka->sa.sa_flags & SA_RESTART)) { 227 regs->er0 = -EINTR; 228 break; 229 } 230 /* fallthrough */ 231 case -ERESTARTNOINTR: 232 do_restart: 233 regs->er0 = regs->orig_er0; 234 regs->pc -= 2; 235 break; 236 } 237 } 238 239 /* 240 * OK, we're invoking a handler 241 */ 242 static void handle_signal(struct ksignal * ksig,struct pt_regs * regs)243 handle_signal(struct ksignal *ksig, struct pt_regs *regs) 244 { 245 sigset_t *oldset = sigmask_to_save(); 246 int ret; 247 /* are we from a system call? */ 248 if (regs->orig_er0 >= 0) 249 handle_restart(regs, &ksig->ka); 250 251 ret = setup_rt_frame(ksig, oldset, regs); 252 253 signal_setup_done(ret, ksig, 0); 254 } 255 256 /* 257 * Note that 'init' is a special process: it doesn't get signals it doesn't 258 * want to handle. Thus you cannot kill init even with a SIGKILL even by 259 * mistake. 260 */ do_signal(struct pt_regs * regs)261 static void do_signal(struct pt_regs *regs) 262 { 263 struct ksignal ksig; 264 265 current->thread.esp0 = (unsigned long) regs; 266 267 if (get_signal(&ksig)) { 268 /* Whee! Actually deliver the signal. */ 269 handle_signal(&ksig, regs); 270 return; 271 } 272 /* Did we come from a system call? */ 273 if (regs->orig_er0 >= 0) 274 handle_restart(regs, NULL); 275 276 /* If there's no signal to deliver, we just restore the saved mask. */ 277 restore_saved_sigmask(); 278 } 279 do_notify_resume(struct pt_regs * regs,u32 thread_info_flags)280 asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) 281 { 282 if (thread_info_flags & _TIF_SIGPENDING) 283 do_signal(regs); 284 285 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 286 clear_thread_flag(TIF_NOTIFY_RESUME); 287 tracehook_notify_resume(regs); 288 } 289 } 290