root/arch/nds32/kernel/signal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. restore_sigcontext_fpu
  2. setup_sigcontext_fpu
  3. restore_sigframe
  4. sys_rt_sigreturn
  5. setup_sigframe
  6. get_sigframe
  7. setup_return
  8. setup_rt_frame
  9. handle_signal
  10. do_signal
  11. do_notify_resume

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (C) 2005-2017 Andes Technology Corporation
   3 
   4 #include <linux/errno.h>
   5 #include <linux/signal.h>
   6 #include <linux/ptrace.h>
   7 #include <linux/personality.h>
   8 #include <linux/freezer.h>
   9 #include <linux/tracehook.h>
  10 #include <linux/uaccess.h>
  11 
  12 #include <asm/cacheflush.h>
  13 #include <asm/ucontext.h>
  14 #include <asm/unistd.h>
  15 #include <asm/fpu.h>
  16 
  17 #include <asm/ptrace.h>
  18 #include <asm/vdso.h>
  19 
  20 struct rt_sigframe {
  21         struct siginfo info;
  22         struct ucontext uc;
  23 };
  24 #if IS_ENABLED(CONFIG_FPU)
  25 static inline int restore_sigcontext_fpu(struct pt_regs *regs,
  26                                          struct sigcontext __user *sc)
  27 {
  28         struct task_struct *tsk = current;
  29         unsigned long used_math_flag;
  30         int ret = 0;
  31 
  32         clear_used_math();
  33         __get_user_error(used_math_flag, &sc->used_math_flag, ret);
  34 
  35         if (!used_math_flag)
  36                 return 0;
  37         set_used_math();
  38 
  39 #if IS_ENABLED(CONFIG_LAZY_FPU)
  40         preempt_disable();
  41         if (current == last_task_used_math) {
  42                 last_task_used_math = NULL;
  43                 disable_ptreg_fpu(regs);
  44         }
  45         preempt_enable();
  46 #else
  47         clear_fpu(regs);
  48 #endif
  49 
  50         return __copy_from_user(&tsk->thread.fpu, &sc->fpu,
  51                                 sizeof(struct fpu_struct));
  52 }
  53 
  54 static inline int setup_sigcontext_fpu(struct pt_regs *regs,
  55                                        struct sigcontext __user *sc)
  56 {
  57         struct task_struct *tsk = current;
  58         int ret = 0;
  59 
  60         __put_user_error(used_math(), &sc->used_math_flag, ret);
  61 
  62         if (!used_math())
  63                 return ret;
  64 
  65         preempt_disable();
  66 #if IS_ENABLED(CONFIG_LAZY_FPU)
  67         if (last_task_used_math == tsk)
  68                 save_fpu(last_task_used_math);
  69 #else
  70         unlazy_fpu(tsk);
  71 #endif
  72         ret = __copy_to_user(&sc->fpu, &tsk->thread.fpu,
  73                              sizeof(struct fpu_struct));
  74         preempt_enable();
  75         return ret;
  76 }
  77 #endif
  78 
  79 static int restore_sigframe(struct pt_regs *regs,
  80                             struct rt_sigframe __user * sf)
  81 {
  82         sigset_t set;
  83         int err;
  84 
  85         err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
  86         if (err == 0) {
  87                 set_current_blocked(&set);
  88         }
  89 
  90         __get_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err);
  91         __get_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err);
  92         __get_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err);
  93         __get_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err);
  94         __get_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err);
  95         __get_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err);
  96         __get_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err);
  97         __get_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err);
  98         __get_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err);
  99         __get_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err);
 100         __get_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err);
 101         __get_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err);
 102         __get_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err);
 103         __get_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err);
 104         __get_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err);
 105         __get_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err);
 106         __get_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err);
 107         __get_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err);
 108         __get_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err);
 109         __get_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err);
 110         __get_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err);
 111         __get_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err);
 112         __get_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err);
 113         __get_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err);
 114         __get_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err);
 115         __get_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err);
 116 
 117         __get_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err);
 118         __get_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err);
 119         __get_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err);
 120         __get_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err);
 121         __get_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err);
 122 #if defined(CONFIG_HWZOL)
 123         __get_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err);
 124         __get_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err);
 125         __get_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err);
 126 #endif
 127 #if IS_ENABLED(CONFIG_FPU)
 128         err |= restore_sigcontext_fpu(regs, &sf->uc.uc_mcontext);
 129 #endif
 130         /*
 131          * Avoid sys_rt_sigreturn() restarting.
 132          */
 133         forget_syscall(regs);
 134         return err;
 135 }
 136 
 137 asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 138 {
 139         struct rt_sigframe __user *frame;
 140 
 141         /* Always make any pending restarted system calls return -EINTR */
 142         current->restart_block.fn = do_no_restart_syscall;
 143 
 144         /*
 145          * Since we stacked the signal on a 64-bit boundary,
 146          * then 'sp' should be two-word aligned here.  If it's
 147          * not, then the user is trying to mess with us.
 148          */
 149         if (regs->sp & 7)
 150                 goto badframe;
 151 
 152         frame = (struct rt_sigframe __user *)regs->sp;
 153 
 154         if (!access_ok(frame, sizeof(*frame)))
 155                 goto badframe;
 156 
 157         if (restore_sigframe(regs, frame))
 158                 goto badframe;
 159 
 160         if (restore_altstack(&frame->uc.uc_stack))
 161                 goto badframe;
 162 
 163         return regs->uregs[0];
 164 
 165 badframe:
 166         force_sig(SIGSEGV);
 167         return 0;
 168 }
 169 
 170 static int
 171 setup_sigframe(struct rt_sigframe __user * sf, struct pt_regs *regs,
 172                sigset_t * set)
 173 {
 174         int err = 0;
 175 
 176         __put_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err);
 177         __put_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err);
 178         __put_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err);
 179         __put_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err);
 180         __put_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err);
 181         __put_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err);
 182         __put_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err);
 183         __put_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err);
 184         __put_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err);
 185         __put_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err);
 186         __put_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err);
 187         __put_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err);
 188         __put_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err);
 189         __put_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err);
 190         __put_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err);
 191         __put_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err);
 192         __put_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err);
 193         __put_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err);
 194         __put_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err);
 195         __put_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err);
 196         __put_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err);
 197 
 198         __put_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err);
 199         __put_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err);
 200         __put_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err);
 201         __put_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err);
 202         __put_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err);
 203         __put_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err);
 204         __put_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err);
 205         __put_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err);
 206         __put_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err);
 207         __put_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err);
 208 #if defined(CONFIG_HWZOL)
 209         __put_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err);
 210         __put_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err);
 211         __put_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err);
 212 #endif
 213 #if IS_ENABLED(CONFIG_FPU)
 214         err |= setup_sigcontext_fpu(regs, &sf->uc.uc_mcontext);
 215 #endif
 216 
 217         __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no,
 218                          err);
 219         __put_user_error(current->thread.error_code,
 220                          &sf->uc.uc_mcontext.error_code, err);
 221         __put_user_error(current->thread.address,
 222                          &sf->uc.uc_mcontext.fault_address, err);
 223         __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
 224 
 225         err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
 226 
 227         return err;
 228 }
 229 
 230 static inline void __user *get_sigframe(struct ksignal *ksig,
 231                                         struct pt_regs *regs, int framesize)
 232 {
 233         unsigned long sp;
 234 
 235         /* Default to using normal stack */
 236         sp = regs->sp;
 237 
 238         /*
 239          * If we are on the alternate signal stack and would overflow it, don't.
 240          * Return an always-bogus address instead so we will die with SIGSEGV.
 241          */
 242         if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
 243                 return (void __user __force *)(-1UL);
 244 
 245         /* This is the X/Open sanctioned signal stack switching. */
 246         sp = (sigsp(sp, ksig) - framesize);
 247 
 248         /*
 249          * nds32 mandates 8-byte alignment
 250          */
 251         sp &= ~0x7UL;
 252 
 253         return (void __user *)sp;
 254 }
 255 
 256 static int
 257 setup_return(struct pt_regs *regs, struct ksignal *ksig, void __user * frame)
 258 {
 259         unsigned long handler = (unsigned long)ksig->ka.sa.sa_handler;
 260         unsigned long retcode;
 261 
 262         retcode = VDSO_SYMBOL(current->mm->context.vdso, rt_sigtramp);
 263         regs->uregs[0] = ksig->sig;
 264         regs->sp = (unsigned long)frame;
 265         regs->lp = retcode;
 266         regs->ipc = handler;
 267 
 268         return 0;
 269 }
 270 
 271 static int
 272 setup_rt_frame(struct ksignal *ksig, sigset_t * set, struct pt_regs *regs)
 273 {
 274         struct rt_sigframe __user *frame =
 275             get_sigframe(ksig, regs, sizeof(*frame));
 276         int err = 0;
 277 
 278         if (!access_ok(frame, sizeof(*frame)))
 279                 return -EFAULT;
 280 
 281         __put_user_error(0, &frame->uc.uc_flags, err);
 282         __put_user_error(NULL, &frame->uc.uc_link, err);
 283 
 284         err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
 285         err |= setup_sigframe(frame, regs, set);
 286         if (err == 0) {
 287                 setup_return(regs, ksig, frame);
 288                 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
 289                         err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 290                         regs->uregs[1] = (unsigned long)&frame->info;
 291                         regs->uregs[2] = (unsigned long)&frame->uc;
 292                 }
 293         }
 294         return err;
 295 }
 296 
 297 /*
 298  * OK, we're invoking a handler
 299  */
 300 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 301 {
 302         int ret;
 303         sigset_t *oldset = sigmask_to_save();
 304 
 305         if (in_syscall(regs)) {
 306                 /* Avoid additional syscall restarting via ret_slow_syscall. */
 307                 forget_syscall(regs);
 308 
 309                 switch (regs->uregs[0]) {
 310                 case -ERESTART_RESTARTBLOCK:
 311                 case -ERESTARTNOHAND:
 312                         regs->uregs[0] = -EINTR;
 313                         break;
 314                 case -ERESTARTSYS:
 315                         if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
 316                                 regs->uregs[0] = -EINTR;
 317                                 break;
 318                         }
 319                         /* Else, fall through */
 320                 case -ERESTARTNOINTR:
 321                         regs->uregs[0] = regs->orig_r0;
 322                         regs->ipc -= 4;
 323                         break;
 324                 }
 325         }
 326         /*
 327          * Set up the stack frame
 328          */
 329         ret = setup_rt_frame(ksig, oldset, regs);
 330 
 331         signal_setup_done(ret, ksig, 0);
 332 }
 333 
 334 /*
 335  * Note that 'init' is a special process: it doesn't get signals it doesn't
 336  * want to handle. Thus you cannot kill init even with a SIGKILL even by
 337  * mistake.
 338  *
 339  * Note that we go through the signals twice: once to check the signals that
 340  * the kernel can handle, and then we build all the user-level signal handling
 341  * stack-frames in one go after that.
 342  */
 343 static void do_signal(struct pt_regs *regs)
 344 {
 345         struct ksignal ksig;
 346 
 347         if (get_signal(&ksig)) {
 348                 handle_signal(&ksig, regs);
 349                 return;
 350         }
 351 
 352         /*
 353          * If we were from a system call, check for system call restarting...
 354          */
 355         if (in_syscall(regs)) {
 356                 /* Restart the system call - no handlers present */
 357 
 358                 /* Avoid additional syscall restarting via ret_slow_syscall. */
 359                 forget_syscall(regs);
 360 
 361                 switch (regs->uregs[0]) {
 362                 case -ERESTART_RESTARTBLOCK:
 363                         regs->uregs[15] = __NR_restart_syscall;
 364                         /* Fall through */
 365                 case -ERESTARTNOHAND:
 366                 case -ERESTARTSYS:
 367                 case -ERESTARTNOINTR:
 368                         regs->uregs[0] = regs->orig_r0;
 369                         regs->ipc -= 0x4;
 370                         break;
 371                 }
 372         }
 373         restore_saved_sigmask();
 374 }
 375 
 376 asmlinkage void
 377 do_notify_resume(struct pt_regs *regs, unsigned int thread_flags)
 378 {
 379         if (thread_flags & _TIF_SIGPENDING)
 380                 do_signal(regs);
 381 
 382         if (thread_flags & _TIF_NOTIFY_RESUME) {
 383                 clear_thread_flag(TIF_NOTIFY_RESUME);
 384                 tracehook_notify_resume(regs);
 385         }
 386 }

/* [<][>][^][v][top][bottom][index][help] */