root/arch/xtensa/kernel/signal.c

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

DEFINITIONS

This source file includes following definitions.
  1. flush_window_regs_user
  2. setup_sigcontext
  3. restore_sigcontext
  4. xtensa_rt_sigreturn
  5. gen_return_code
  6. setup_frame
  7. do_signal
  8. do_notify_resume

   1 /*
   2  * arch/xtensa/kernel/signal.c
   3  *
   4  * Default platform functions.
   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  * Copyright (C) 2005, 2006 Tensilica Inc.
  11  * Copyright (C) 1991, 1992  Linus Torvalds
  12  * 1997-11-28  Modified for POSIX.1b signals by Richard Henderson
  13  *
  14  * Chris Zankel <chris@zankel.net>
  15  * Joe Taylor <joe@tensilica.com>
  16  */
  17 
  18 #include <linux/signal.h>
  19 #include <linux/errno.h>
  20 #include <linux/ptrace.h>
  21 #include <linux/personality.h>
  22 #include <linux/tracehook.h>
  23 #include <linux/sched/task_stack.h>
  24 
  25 #include <asm/ucontext.h>
  26 #include <linux/uaccess.h>
  27 #include <asm/cacheflush.h>
  28 #include <asm/coprocessor.h>
  29 #include <asm/unistd.h>
  30 
  31 extern struct task_struct *coproc_owners[];
  32 
  33 struct rt_sigframe
  34 {
  35         struct siginfo info;
  36         struct ucontext uc;
  37         struct {
  38                 xtregs_opt_t opt;
  39                 xtregs_user_t user;
  40 #if XTENSA_HAVE_COPROCESSORS
  41                 xtregs_coprocessor_t cp;
  42 #endif
  43         } xtregs;
  44         unsigned char retcode[6];
  45         unsigned int window[4];
  46 };
  47 
  48 /* 
  49  * Flush register windows stored in pt_regs to stack.
  50  * Returns 1 for errors.
  51  */
  52 
  53 int
  54 flush_window_regs_user(struct pt_regs *regs)
  55 {
  56         const unsigned long ws = regs->windowstart;
  57         const unsigned long wb = regs->windowbase;
  58         unsigned long sp = 0;
  59         unsigned long wm;
  60         int err = 1;
  61         int base;
  62 
  63         /* Return if no other frames. */
  64 
  65         if (regs->wmask == 1)
  66                 return 0;
  67 
  68         /* Rotate windowmask and skip empty frames. */
  69 
  70         wm = (ws >> wb) | (ws << (XCHAL_NUM_AREGS / 4 - wb));
  71         base = (XCHAL_NUM_AREGS / 4) - (regs->wmask >> 4);
  72                 
  73         /* For call8 or call12 frames, we need the previous stack pointer. */
  74 
  75         if ((regs->wmask & 2) == 0)
  76                 if (__get_user(sp, (int*)(regs->areg[base * 4 + 1] - 12)))
  77                         goto errout;
  78 
  79         /* Spill frames to stack. */
  80 
  81         while (base < XCHAL_NUM_AREGS / 4) {
  82 
  83                 int m = (wm >> base);
  84                 int inc = 0;
  85 
  86                 /* Save registers a4..a7 (call8) or a4...a11 (call12) */
  87 
  88                 if (m & 2) {                    /* call4 */
  89                         inc = 1;
  90 
  91                 } else if (m & 4) {             /* call8 */
  92                         if (copy_to_user(&SPILL_SLOT_CALL8(sp, 4),
  93                                          &regs->areg[(base + 1) * 4], 16))
  94                                 goto errout;
  95                         inc = 2;
  96 
  97                 } else if (m & 8) {     /* call12 */
  98                         if (copy_to_user(&SPILL_SLOT_CALL12(sp, 4),
  99                                          &regs->areg[(base + 1) * 4], 32))
 100                                 goto errout;
 101                         inc = 3;
 102                 }
 103 
 104                 /* Save current frame a0..a3 under next SP */
 105 
 106                 sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS];
 107                 if (copy_to_user(&SPILL_SLOT(sp, 0), &regs->areg[base * 4], 16))
 108                         goto errout;
 109 
 110                 /* Get current stack pointer for next loop iteration. */
 111 
 112                 sp = regs->areg[base * 4 + 1];
 113                 base += inc;
 114         }
 115 
 116         regs->wmask = 1;
 117         regs->windowstart = 1 << wb;
 118 
 119         return 0;
 120 
 121 errout:
 122         return err;
 123 }
 124 
 125 /*
 126  * Note: We don't copy double exception 'regs', we have to finish double exc. 
 127  * first before we return to signal handler! This dbl.exc.handler might cause 
 128  * another double exception, but I think we are fine as the situation is the 
 129  * same as if we had returned to the signal handerl and got an interrupt 
 130  * immediately...
 131  */
 132 
 133 static int
 134 setup_sigcontext(struct rt_sigframe __user *frame, struct pt_regs *regs)
 135 {
 136         struct sigcontext __user *sc = &frame->uc.uc_mcontext;
 137         struct thread_info *ti = current_thread_info();
 138         int err = 0;
 139 
 140 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
 141         COPY(pc);
 142         COPY(ps);
 143         COPY(lbeg);
 144         COPY(lend);
 145         COPY(lcount);
 146         COPY(sar);
 147 #undef COPY
 148 
 149         err |= flush_window_regs_user(regs);
 150         err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4);
 151         err |= __put_user(0, &sc->sc_xtregs);
 152 
 153         if (err)
 154                 return err;
 155 
 156 #if XTENSA_HAVE_COPROCESSORS
 157         coprocessor_flush_all(ti);
 158         coprocessor_release_all(ti);
 159         err |= __copy_to_user(&frame->xtregs.cp, &ti->xtregs_cp,
 160                               sizeof (frame->xtregs.cp));
 161 #endif
 162         err |= __copy_to_user(&frame->xtregs.opt, &regs->xtregs_opt,
 163                               sizeof (xtregs_opt_t));
 164         err |= __copy_to_user(&frame->xtregs.user, &ti->xtregs_user,
 165                               sizeof (xtregs_user_t));
 166 
 167         err |= __put_user(err ? NULL : &frame->xtregs, &sc->sc_xtregs);
 168 
 169         return err;
 170 }
 171 
 172 static int
 173 restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame)
 174 {
 175         struct sigcontext __user *sc = &frame->uc.uc_mcontext;
 176         struct thread_info *ti = current_thread_info();
 177         unsigned int err = 0;
 178         unsigned long ps;
 179 
 180 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
 181         COPY(pc);
 182         COPY(lbeg);
 183         COPY(lend);
 184         COPY(lcount);
 185         COPY(sar);
 186 #undef COPY
 187 
 188         /* All registers were flushed to stack. Start with a pristine frame. */
 189 
 190         regs->wmask = 1;
 191         regs->windowbase = 0;
 192         regs->windowstart = 1;
 193 
 194         regs->syscall = NO_SYSCALL;     /* disable syscall checks */
 195 
 196         /* For PS, restore only PS.CALLINC.
 197          * Assume that all other bits are either the same as for the signal
 198          * handler, or the user mode value doesn't matter (e.g. PS.OWB).
 199          */
 200         err |= __get_user(ps, &sc->sc_ps);
 201         regs->ps = (regs->ps & ~PS_CALLINC_MASK) | (ps & PS_CALLINC_MASK);
 202 
 203         /* Additional corruption checks */
 204 
 205         if ((regs->lcount > 0)
 206             && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
 207                 err = 1;
 208 
 209         err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4);
 210 
 211         if (err)
 212                 return err;
 213 
 214         /* The signal handler may have used coprocessors in which
 215          * case they are still enabled.  We disable them to force a
 216          * reloading of the original task's CP state by the lazy
 217          * context-switching mechanisms of CP exception handling.
 218          * Also, we essentially discard any coprocessor state that the
 219          * signal handler created. */
 220 
 221 #if XTENSA_HAVE_COPROCESSORS
 222         coprocessor_release_all(ti);
 223         err |= __copy_from_user(&ti->xtregs_cp, &frame->xtregs.cp,
 224                                 sizeof (frame->xtregs.cp));
 225 #endif
 226         err |= __copy_from_user(&ti->xtregs_user, &frame->xtregs.user,
 227                                 sizeof (xtregs_user_t));
 228         err |= __copy_from_user(&regs->xtregs_opt, &frame->xtregs.opt,
 229                                 sizeof (xtregs_opt_t));
 230 
 231         return err;
 232 }
 233 
 234 
 235 /*
 236  * Do a signal return; undo the signal stack.
 237  */
 238 
 239 asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,
 240                                     long a4, long a5, struct pt_regs *regs)
 241 {
 242         struct rt_sigframe __user *frame;
 243         sigset_t set;
 244         int ret;
 245 
 246         /* Always make any pending restarted system calls return -EINTR */
 247         current->restart_block.fn = do_no_restart_syscall;
 248 
 249         if (regs->depc > 64)
 250                 panic("rt_sigreturn in double exception!\n");
 251 
 252         frame = (struct rt_sigframe __user *) regs->areg[1];
 253 
 254         if (!access_ok(frame, sizeof(*frame)))
 255                 goto badframe;
 256 
 257         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 258                 goto badframe;
 259 
 260         set_current_blocked(&set);
 261 
 262         if (restore_sigcontext(regs, frame))
 263                 goto badframe;
 264 
 265         ret = regs->areg[2];
 266 
 267         if (restore_altstack(&frame->uc.uc_stack))
 268                 goto badframe;
 269 
 270         return ret;
 271 
 272 badframe:
 273         force_sig(SIGSEGV);
 274         return 0;
 275 }
 276 
 277 
 278 
 279 /*
 280  * Set up a signal frame.
 281  */
 282 
 283 static int
 284 gen_return_code(unsigned char *codemem)
 285 {
 286         int err = 0;
 287 
 288         /*
 289          * The 12-bit immediate is really split up within the 24-bit MOVI
 290          * instruction.  As long as the above system call numbers fit within
 291          * 8-bits, the following code works fine. See the Xtensa ISA for
 292          * details.
 293          */
 294 
 295 #if __NR_rt_sigreturn > 255
 296 # error Generating the MOVI instruction below breaks!
 297 #endif
 298 
 299 #ifdef __XTENSA_EB__   /* Big Endian version */
 300         /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
 301         err |= __put_user(0x22, &codemem[0]);
 302         err |= __put_user(0x0a, &codemem[1]);
 303         err |= __put_user(__NR_rt_sigreturn, &codemem[2]);
 304         /* Generate instruction:  SYSCALL */
 305         err |= __put_user(0x00, &codemem[3]);
 306         err |= __put_user(0x05, &codemem[4]);
 307         err |= __put_user(0x00, &codemem[5]);
 308 
 309 #elif defined __XTENSA_EL__   /* Little Endian version */
 310         /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
 311         err |= __put_user(0x22, &codemem[0]);
 312         err |= __put_user(0xa0, &codemem[1]);
 313         err |= __put_user(__NR_rt_sigreturn, &codemem[2]);
 314         /* Generate instruction:  SYSCALL */
 315         err |= __put_user(0x00, &codemem[3]);
 316         err |= __put_user(0x50, &codemem[4]);
 317         err |= __put_user(0x00, &codemem[5]);
 318 #else
 319 # error Must use compiler for Xtensa processors.
 320 #endif
 321 
 322         /* Flush generated code out of the data cache */
 323 
 324         if (err == 0) {
 325                 __invalidate_icache_range((unsigned long)codemem, 6UL);
 326                 __flush_invalidate_dcache_range((unsigned long)codemem, 6UL);
 327         }
 328 
 329         return err;
 330 }
 331 
 332 
 333 static int setup_frame(struct ksignal *ksig, sigset_t *set,
 334                        struct pt_regs *regs)
 335 {
 336         struct rt_sigframe *frame;
 337         int err = 0, sig = ksig->sig;
 338         unsigned long sp, ra, tp, ps;
 339         unsigned int base;
 340 
 341         sp = regs->areg[1];
 342 
 343         if ((ksig->ka.sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
 344                 sp = current->sas_ss_sp + current->sas_ss_size;
 345         }
 346 
 347         frame = (void *)((sp - sizeof(*frame)) & -16ul);
 348 
 349         if (regs->depc > 64)
 350                 panic ("Double exception sys_sigreturn\n");
 351 
 352         if (!access_ok(frame, sizeof(*frame))) {
 353                 return -EFAULT;
 354         }
 355 
 356         if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
 357                 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 358         }
 359 
 360         /* Create the user context.  */
 361 
 362         err |= __put_user(0, &frame->uc.uc_flags);
 363         err |= __put_user(0, &frame->uc.uc_link);
 364         err |= __save_altstack(&frame->uc.uc_stack, regs->areg[1]);
 365         err |= setup_sigcontext(frame, regs);
 366         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 367 
 368         if (ksig->ka.sa.sa_flags & SA_RESTORER) {
 369                 ra = (unsigned long)ksig->ka.sa.sa_restorer;
 370         } else {
 371 
 372                 /* Create sys_rt_sigreturn syscall in stack frame */
 373 
 374                 err |= gen_return_code(frame->retcode);
 375 
 376                 if (err) {
 377                         return -EFAULT;
 378                 }
 379                 ra = (unsigned long) frame->retcode;
 380         }
 381 
 382         /* 
 383          * Create signal handler execution context.
 384          * Return context not modified until this point.
 385          */
 386 
 387         /* Set up registers for signal handler; preserve the threadptr */
 388         tp = regs->threadptr;
 389         ps = regs->ps;
 390         start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler,
 391                      (unsigned long) frame);
 392 
 393         /* Set up a stack frame for a call4 if userspace uses windowed ABI */
 394         if (ps & PS_WOE_MASK) {
 395                 base = 4;
 396                 regs->areg[base] =
 397                         (((unsigned long) ra) & 0x3fffffff) | 0x40000000;
 398                 ps = (ps & ~(PS_CALLINC_MASK | PS_OWB_MASK)) |
 399                         (1 << PS_CALLINC_SHIFT);
 400         } else {
 401                 base = 0;
 402                 regs->areg[base] = (unsigned long) ra;
 403         }
 404         regs->areg[base + 2] = (unsigned long) sig;
 405         regs->areg[base + 3] = (unsigned long) &frame->info;
 406         regs->areg[base + 4] = (unsigned long) &frame->uc;
 407         regs->threadptr = tp;
 408         regs->ps = ps;
 409 
 410         pr_debug("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08lx\n",
 411                  current->comm, current->pid, sig, frame, regs->pc);
 412 
 413         return 0;
 414 }
 415 
 416 /*
 417  * Note that 'init' is a special process: it doesn't get signals it doesn't
 418  * want to handle. Thus you cannot kill init even with a SIGKILL even by
 419  * mistake.
 420  *
 421  * Note that we go through the signals twice: once to check the signals that
 422  * the kernel can handle, and then we build all the user-level signal handling
 423  * stack-frames in one go after that.
 424  */
 425 static void do_signal(struct pt_regs *regs)
 426 {
 427         struct ksignal ksig;
 428 
 429         task_pt_regs(current)->icountlevel = 0;
 430 
 431         if (get_signal(&ksig)) {
 432                 int ret;
 433 
 434                 /* Are we from a system call? */
 435 
 436                 if (regs->syscall != NO_SYSCALL) {
 437 
 438                         /* If so, check system call restarting.. */
 439 
 440                         switch (regs->areg[2]) {
 441                                 case -ERESTARTNOHAND:
 442                                 case -ERESTART_RESTARTBLOCK:
 443                                         regs->areg[2] = -EINTR;
 444                                         break;
 445 
 446                                 case -ERESTARTSYS:
 447                                         if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
 448                                                 regs->areg[2] = -EINTR;
 449                                                 break;
 450                                         }
 451                                         /* fallthrough */
 452                                 case -ERESTARTNOINTR:
 453                                         regs->areg[2] = regs->syscall;
 454                                         regs->pc -= 3;
 455                                         break;
 456 
 457                                 default:
 458                                         /* nothing to do */
 459                                         if (regs->areg[2] != 0)
 460                                         break;
 461                         }
 462                 }
 463 
 464                 /* Whee!  Actually deliver the signal.  */
 465                 /* Set up the stack frame */
 466                 ret = setup_frame(&ksig, sigmask_to_save(), regs);
 467                 signal_setup_done(ret, &ksig, 0);
 468                 if (current->ptrace & PT_SINGLESTEP)
 469                         task_pt_regs(current)->icountlevel = 1;
 470 
 471                 return;
 472         }
 473 
 474         /* Did we come from a system call? */
 475         if (regs->syscall != NO_SYSCALL) {
 476                 /* Restart the system call - no handlers present */
 477                 switch (regs->areg[2]) {
 478                 case -ERESTARTNOHAND:
 479                 case -ERESTARTSYS:
 480                 case -ERESTARTNOINTR:
 481                         regs->areg[2] = regs->syscall;
 482                         regs->pc -= 3;
 483                         break;
 484                 case -ERESTART_RESTARTBLOCK:
 485                         regs->areg[2] = __NR_restart_syscall;
 486                         regs->pc -= 3;
 487                         break;
 488                 }
 489         }
 490 
 491         /* If there's no signal to deliver, we just restore the saved mask.  */
 492         restore_saved_sigmask();
 493 
 494         if (current->ptrace & PT_SINGLESTEP)
 495                 task_pt_regs(current)->icountlevel = 1;
 496         return;
 497 }
 498 
 499 void do_notify_resume(struct pt_regs *regs)
 500 {
 501         if (test_thread_flag(TIF_SIGPENDING))
 502                 do_signal(regs);
 503 
 504         if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME))
 505                 tracehook_notify_resume(regs);
 506 }

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