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