root/arch/parisc/kernel/signal.c

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

DEFINITIONS

This source file includes following definitions.
  1. restore_sigcontext
  2. sys_rt_sigreturn
  3. get_sigframe
  4. setup_sigcontext
  5. setup_rt_frame
  6. handle_signal
  7. check_syscallno_in_delay_branch
  8. syscall_restart
  9. insert_restart_trampoline
  10. do_signal
  11. do_notify_resume

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  linux/arch/parisc/kernel/signal.c: Architecture-specific signal
   4  *  handling support.
   5  *
   6  *  Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
   7  *  Copyright (C) 2000 Linuxcare, Inc.
   8  *
   9  *  Based on the ia64, i386, and alpha versions.
  10  *
  11  *  Like the IA-64, we are a recent enough port (we are *starting*
  12  *  with glibc2.2) that we do not need to support the old non-realtime
  13  *  Linux signals.  Therefore we don't.
  14  */
  15 
  16 #include <linux/sched.h>
  17 #include <linux/sched/debug.h>
  18 #include <linux/mm.h>
  19 #include <linux/smp.h>
  20 #include <linux/kernel.h>
  21 #include <linux/signal.h>
  22 #include <linux/errno.h>
  23 #include <linux/wait.h>
  24 #include <linux/ptrace.h>
  25 #include <linux/tracehook.h>
  26 #include <linux/unistd.h>
  27 #include <linux/stddef.h>
  28 #include <linux/compat.h>
  29 #include <linux/elf.h>
  30 #include <asm/ucontext.h>
  31 #include <asm/rt_sigframe.h>
  32 #include <linux/uaccess.h>
  33 #include <asm/pgalloc.h>
  34 #include <asm/cacheflush.h>
  35 #include <asm/asm-offsets.h>
  36 
  37 #ifdef CONFIG_COMPAT
  38 #include "signal32.h"
  39 #endif
  40 
  41 #define DEBUG_SIG 0 
  42 #define DEBUG_SIG_LEVEL 2
  43 
  44 #if DEBUG_SIG
  45 #define DBG(LEVEL, ...) \
  46         ((DEBUG_SIG_LEVEL >= LEVEL) \
  47         ? printk(__VA_ARGS__) : (void) 0)
  48 #else
  49 #define DBG(LEVEL, ...)
  50 #endif
  51         
  52 /* gcc will complain if a pointer is cast to an integer of different
  53  * size.  If you really need to do this (and we do for an ELF32 user
  54  * application in an ELF64 kernel) then you have to do a cast to an
  55  * integer of the same size first.  The A() macro accomplishes
  56  * this. */
  57 #define A(__x)  ((unsigned long)(__x))
  58 
  59 /*
  60  * Do a signal return - restore sigcontext.
  61  */
  62 
  63 /* Trampoline for calling rt_sigreturn() */
  64 #define INSN_LDI_R25_0   0x34190000 /* ldi  0,%r25 (in_syscall=0) */
  65 #define INSN_LDI_R25_1   0x34190002 /* ldi  1,%r25 (in_syscall=1) */
  66 #define INSN_LDI_R20     0x3414015a /* ldi  __NR_rt_sigreturn,%r20 */
  67 #define INSN_BLE_SR2_R0  0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
  68 /* For debugging */
  69 #define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
  70 
  71 static long
  72 restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
  73 {
  74         long err = 0;
  75 
  76         err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr));
  77         err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
  78         err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq));
  79         err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq));
  80         err |= __get_user(regs->sar, &sc->sc_sar);
  81         DBG(2,"restore_sigcontext: iaoq is %#lx / %#lx\n",
  82                         regs->iaoq[0],regs->iaoq[1]);
  83         DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]);
  84         return err;
  85 }
  86 
  87 void
  88 sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
  89 {
  90         struct rt_sigframe __user *frame;
  91         sigset_t set;
  92         unsigned long usp = (regs->gr[30] & ~(0x01UL));
  93         unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
  94 #ifdef CONFIG_64BIT
  95         struct compat_rt_sigframe __user * compat_frame;
  96         
  97         if (is_compat_task())
  98                 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
  99 #endif
 100 
 101         current->restart_block.fn = do_no_restart_syscall;
 102 
 103         /* Unwind the user stack to get the rt_sigframe structure. */
 104         frame = (struct rt_sigframe __user *)
 105                 (usp - sigframe_size);
 106         DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
 107 
 108         regs->orig_r28 = 1; /* no restarts for sigreturn */
 109 
 110 #ifdef CONFIG_64BIT
 111         compat_frame = (struct compat_rt_sigframe __user *)frame;
 112         
 113         if (is_compat_task()) {
 114                 DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
 115                 if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask))
 116                         goto give_sigsegv;
 117         } else
 118 #endif
 119         {
 120                 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 121                         goto give_sigsegv;
 122         }
 123                 
 124         set_current_blocked(&set);
 125 
 126         /* Good thing we saved the old gr[30], eh? */
 127 #ifdef CONFIG_64BIT
 128         if (is_compat_task()) {
 129                 DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
 130                                 &compat_frame->uc.uc_mcontext);
 131 // FIXME: Load upper half from register file
 132                 if (restore_sigcontext32(&compat_frame->uc.uc_mcontext, 
 133                                         &compat_frame->regs, regs))
 134                         goto give_sigsegv;
 135                 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
 136                                 usp, &compat_frame->uc.uc_stack);
 137                 if (compat_restore_altstack(&compat_frame->uc.uc_stack))
 138                         goto give_sigsegv;
 139         } else
 140 #endif
 141         {
 142                 DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n",
 143                                 &frame->uc.uc_mcontext);
 144                 if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
 145                         goto give_sigsegv;
 146                 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
 147                                 usp, &frame->uc.uc_stack);
 148                 if (restore_altstack(&frame->uc.uc_stack))
 149                         goto give_sigsegv;
 150         }
 151                 
 152 
 153 
 154         /* If we are on the syscall path IAOQ will not be restored, and
 155          * if we are on the interrupt path we must not corrupt gr31.
 156          */
 157         if (in_syscall)
 158                 regs->gr[31] = regs->iaoq[0];
 159 #if DEBUG_SIG
 160         DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]);
 161         show_regs(regs);
 162 #endif
 163         return;
 164 
 165 give_sigsegv:
 166         DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
 167         force_sig(SIGSEGV);
 168         return;
 169 }
 170 
 171 /*
 172  * Set up a signal frame.
 173  */
 174 
 175 static inline void __user *
 176 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
 177 {
 178         /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
 179           don't use the parameter it doesn't matter */
 180 
 181         DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
 182                         (unsigned long)ka, sp, frame_size);
 183         
 184         /* Align alternate stack and reserve 64 bytes for the signal
 185            handler's frame marker.  */
 186         if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
 187                 sp = (current->sas_ss_sp + 0x7f) & ~0x3f; /* Stacks grow up! */
 188 
 189         DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
 190         return (void __user *) sp; /* Stacks grow up.  Fun. */
 191 }
 192 
 193 static long
 194 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall)
 195                  
 196 {
 197         unsigned long flags = 0;
 198         long err = 0;
 199 
 200         if (on_sig_stack((unsigned long) sc))
 201                 flags |= PARISC_SC_FLAG_ONSTACK;
 202         if (in_syscall) {
 203                 flags |= PARISC_SC_FLAG_IN_SYSCALL;
 204                 /* regs->iaoq is undefined in the syscall return path */
 205                 err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]);
 206                 err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]);
 207                 err |= __put_user(regs->sr[3], &sc->sc_iasq[0]);
 208                 err |= __put_user(regs->sr[3], &sc->sc_iasq[1]);
 209                 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n",
 210                         regs->gr[31], regs->gr[31]+4);
 211         } else {
 212                 err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq));
 213                 err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq));
 214                 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n", 
 215                         regs->iaoq[0], regs->iaoq[1]);
 216         }
 217 
 218         err |= __put_user(flags, &sc->sc_flags);
 219         err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr));
 220         err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
 221         err |= __put_user(regs->sar, &sc->sc_sar);
 222         DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]);
 223 
 224         return err;
 225 }
 226 
 227 static long
 228 setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
 229                int in_syscall)
 230 {
 231         struct rt_sigframe __user *frame;
 232         unsigned long rp, usp;
 233         unsigned long haddr, sigframe_size;
 234         unsigned long start, end;
 235         int err = 0;
 236 #ifdef CONFIG_64BIT
 237         struct compat_rt_sigframe __user * compat_frame;
 238 #endif
 239         
 240         usp = (regs->gr[30] & ~(0x01UL));
 241         /*FIXME: frame_size parameter is unused, remove it. */
 242         frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
 243 
 244         DBG(1,"SETUP_RT_FRAME: START\n");
 245         DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
 246 
 247         
 248 #ifdef CONFIG_64BIT
 249 
 250         compat_frame = (struct compat_rt_sigframe __user *)frame;
 251         
 252         if (is_compat_task()) {
 253                 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
 254                 err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info);
 255                 err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
 256                 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
 257                 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
 258                 err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 
 259                                         &compat_frame->regs, regs, in_syscall);
 260                 err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set,
 261                                          sizeof(compat_sigset_t));
 262         } else
 263 #endif
 264         {       
 265                 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
 266                 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 267                 err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
 268                 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
 269                 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
 270                 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
 271                 /* FIXME: Should probably be converted as well for the compat case */
 272                 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 273         }
 274         
 275         if (err)
 276                 return -EFAULT;
 277 
 278         /* Set up to return from userspace.  If provided, use a stub
 279            already in userspace. The first words of tramp are used to
 280            save the previous sigrestartblock trampoline that might be
 281            on the stack. We start the sigreturn trampoline at 
 282            SIGRESTARTBLOCK_TRAMP+X. */
 283         err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
 284                         &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
 285         err |= __put_user(INSN_LDI_R20, 
 286                         &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
 287         err |= __put_user(INSN_BLE_SR2_R0, 
 288                         &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
 289         err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
 290 
 291 #if DEBUG_SIG
 292         /* Assert that we're flushing in the correct space... */
 293         {
 294                 unsigned long sid;
 295                 asm ("mfsp %%sr3,%0" : "=r" (sid));
 296                 DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
 297                        sid, frame->tramp);
 298         }
 299 #endif
 300 
 301         start = (unsigned long) &frame->tramp[0];
 302         end = (unsigned long) &frame->tramp[TRAMP_SIZE];
 303         flush_user_dcache_range_asm(start, end);
 304         flush_user_icache_range_asm(start, end);
 305 
 306         /* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP
 307          * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
 308          * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
 309          */
 310         rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
 311 
 312         if (err)
 313                 return -EFAULT;
 314 
 315         haddr = A(ksig->ka.sa.sa_handler);
 316         /* The sa_handler may be a pointer to a function descriptor */
 317 #ifdef CONFIG_64BIT
 318         if (is_compat_task()) {
 319 #endif
 320                 if (haddr & PA_PLABEL_FDESC) {
 321                         Elf32_Fdesc fdesc;
 322                         Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3);
 323 
 324                         err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
 325 
 326                         if (err)
 327                                 return -EFAULT;
 328 
 329                         haddr = fdesc.addr;
 330                         regs->gr[19] = fdesc.gp;
 331                 }
 332 #ifdef CONFIG_64BIT
 333         } else {
 334                 Elf64_Fdesc fdesc;
 335                 Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
 336                 
 337                 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
 338                 
 339                 if (err)
 340                         return -EFAULT;
 341                 
 342                 haddr = fdesc.addr;
 343                 regs->gr[19] = fdesc.gp;
 344                 DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
 345                      haddr, regs->gr[19], in_syscall);
 346         }
 347 #endif
 348 
 349         /* The syscall return path will create IAOQ values from r31.
 350          */
 351         sigframe_size = PARISC_RT_SIGFRAME_SIZE;
 352 #ifdef CONFIG_64BIT
 353         if (is_compat_task())
 354                 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
 355 #endif
 356         if (in_syscall) {
 357                 regs->gr[31] = haddr;
 358 #ifdef CONFIG_64BIT
 359                 if (!test_thread_flag(TIF_32BIT))
 360                         sigframe_size |= 1;
 361 #endif
 362         } else {
 363                 unsigned long psw = USER_PSW;
 364 #ifdef CONFIG_64BIT
 365                 if (!test_thread_flag(TIF_32BIT))
 366                         psw |= PSW_W;
 367 #endif
 368 
 369                 /* If we are singlestepping, arrange a trap to be delivered
 370                    when we return to userspace. Note the semantics -- we
 371                    should trap before the first insn in the handler is
 372                    executed. Ref:
 373                         http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
 374                  */
 375                 if (pa_psw(current)->r) {
 376                         pa_psw(current)->r = 0;
 377                         psw |= PSW_R;
 378                         mtctl(-1, 0);
 379                 }
 380 
 381                 regs->gr[0] = psw;
 382                 regs->iaoq[0] = haddr | 3;
 383                 regs->iaoq[1] = regs->iaoq[0] + 4;
 384         }
 385 
 386         regs->gr[2]  = rp;                /* userland return pointer */
 387         regs->gr[26] = ksig->sig;               /* signal number */
 388         
 389 #ifdef CONFIG_64BIT
 390         if (is_compat_task()) {
 391                 regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
 392                 regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
 393         } else
 394 #endif
 395         {               
 396                 regs->gr[25] = A(&frame->info); /* siginfo pointer */
 397                 regs->gr[24] = A(&frame->uc);   /* ucontext pointer */
 398         }
 399         
 400         DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
 401                regs->gr[30], sigframe_size,
 402                regs->gr[30] + sigframe_size);
 403         /* Raise the user stack pointer to make a proper call frame. */
 404         regs->gr[30] = (A(frame) + sigframe_size);
 405 
 406 
 407         DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
 408                current->comm, current->pid, frame, regs->gr[30],
 409                regs->iaoq[0], regs->iaoq[1], rp);
 410 
 411         return 0;
 412 }
 413 
 414 /*
 415  * OK, we're invoking a handler.
 416  */     
 417 
 418 static void
 419 handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
 420 {
 421         int ret;
 422         sigset_t *oldset = sigmask_to_save();
 423 
 424         DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
 425                ksig->sig, ksig->ka, ksig->info, oldset, regs);
 426         
 427         /* Set up the stack frame */
 428         ret = setup_rt_frame(ksig, oldset, regs, in_syscall);
 429 
 430         signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) ||
 431                           test_thread_flag(TIF_BLOCKSTEP));
 432 
 433         DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
 434                 regs->gr[28]);
 435 }
 436 
 437 /*
 438  * Check how the syscall number gets loaded into %r20 within
 439  * the delay branch in userspace and adjust as needed.
 440  */
 441 
 442 static void check_syscallno_in_delay_branch(struct pt_regs *regs)
 443 {
 444         u32 opcode, source_reg;
 445         u32 __user *uaddr;
 446         int err;
 447 
 448         /* Usually we don't have to restore %r20 (the system call number)
 449          * because it gets loaded in the delay slot of the branch external
 450          * instruction via the ldi instruction.
 451          * In some cases a register-to-register copy instruction might have
 452          * been used instead, in which case we need to copy the syscall
 453          * number into the source register before returning to userspace.
 454          */
 455 
 456         /* A syscall is just a branch, so all we have to do is fiddle the
 457          * return pointer so that the ble instruction gets executed again.
 458          */
 459         regs->gr[31] -= 8; /* delayed branching */
 460 
 461         /* Get assembler opcode of code in delay branch */
 462         uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4);
 463         err = get_user(opcode, uaddr);
 464         if (err)
 465                 return;
 466 
 467         /* Check if delay branch uses "ldi int,%r20" */
 468         if ((opcode & 0xffff0000) == 0x34140000)
 469                 return; /* everything ok, just return */
 470 
 471         /* Check if delay branch uses "nop" */
 472         if (opcode == INSN_NOP)
 473                 return;
 474 
 475         /* Check if delay branch uses "copy %rX,%r20" */
 476         if ((opcode & 0xffe0ffff) == 0x08000254) {
 477                 source_reg = (opcode >> 16) & 31;
 478                 regs->gr[source_reg] = regs->gr[20];
 479                 return;
 480         }
 481 
 482         pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n",
 483                 current->comm, task_pid_nr(current), opcode);
 484 }
 485 
 486 static inline void
 487 syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 488 {
 489         if (regs->orig_r28)
 490                 return;
 491         regs->orig_r28 = 1; /* no more restarts */
 492         /* Check the return code */
 493         switch (regs->gr[28]) {
 494         case -ERESTART_RESTARTBLOCK:
 495         case -ERESTARTNOHAND:
 496                 DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
 497                 regs->gr[28] = -EINTR;
 498                 break;
 499 
 500         case -ERESTARTSYS:
 501                 if (!(ka->sa.sa_flags & SA_RESTART)) {
 502                         DBG(1,"ERESTARTSYS: putting -EINTR\n");
 503                         regs->gr[28] = -EINTR;
 504                         break;
 505                 }
 506                 /* fallthrough */
 507         case -ERESTARTNOINTR:
 508                 check_syscallno_in_delay_branch(regs);
 509                 break;
 510         }
 511 }
 512 
 513 static inline void
 514 insert_restart_trampoline(struct pt_regs *regs)
 515 {
 516         if (regs->orig_r28)
 517                 return;
 518         regs->orig_r28 = 1; /* no more restarts */
 519         switch(regs->gr[28]) {
 520         case -ERESTART_RESTARTBLOCK: {
 521                 /* Restart the system call - no handlers present */
 522                 unsigned int *usp = (unsigned int *)regs->gr[30];
 523                 unsigned long start = (unsigned long) &usp[2];
 524                 unsigned long end  = (unsigned long) &usp[5];
 525                 long err = 0;
 526 
 527                 /* Setup a trampoline to restart the syscall
 528                  * with __NR_restart_syscall
 529                  *
 530                  *  0: <return address (orig r31)>
 531                  *  4: <2nd half for 64-bit>
 532                  *  8: ldw 0(%sp), %r31
 533                  * 12: be 0x100(%sr2, %r0)
 534                  * 16: ldi __NR_restart_syscall, %r20
 535                  */
 536 #ifdef CONFIG_64BIT
 537                 err |= put_user(regs->gr[31] >> 32, &usp[0]);
 538                 err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]);
 539                 err |= put_user(0x0fc010df, &usp[2]);
 540 #else
 541                 err |= put_user(regs->gr[31], &usp[0]);
 542                 err |= put_user(0x0fc0109f, &usp[2]);
 543 #endif
 544                 err |= put_user(0xe0008200, &usp[3]);
 545                 err |= put_user(0x34140000, &usp[4]);
 546 
 547                 WARN_ON(err);
 548 
 549                 /* flush data/instruction cache for new insns */
 550                 flush_user_dcache_range_asm(start, end);
 551                 flush_user_icache_range_asm(start, end);
 552 
 553                 regs->gr[31] = regs->gr[30] + 8;
 554                 return;
 555         }
 556         case -ERESTARTNOHAND:
 557         case -ERESTARTSYS:
 558         case -ERESTARTNOINTR:
 559                 check_syscallno_in_delay_branch(regs);
 560                 return;
 561         default:
 562                 break;
 563         }
 564 }
 565 
 566 /*
 567  * Note that 'init' is a special process: it doesn't get signals it doesn't
 568  * want to handle. Thus you cannot kill init even with a SIGKILL even by
 569  * mistake.
 570  *
 571  * We need to be able to restore the syscall arguments (r21-r26) to
 572  * restart syscalls.  Thus, the syscall path should save them in the
 573  * pt_regs structure (it's okay to do so since they are caller-save
 574  * registers).  As noted below, the syscall number gets restored for
 575  * us due to the magic of delayed branching.
 576  */
 577 asmlinkage void
 578 do_signal(struct pt_regs *regs, long in_syscall)
 579 {
 580         struct ksignal ksig;
 581 
 582         DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
 583                regs, regs->sr[7], in_syscall);
 584 
 585         if (get_signal(&ksig)) {
 586                 DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
 587                 /* Restart a system call if necessary. */
 588                 if (in_syscall)
 589                         syscall_restart(regs, &ksig.ka);
 590 
 591                 handle_signal(&ksig, regs, in_syscall);
 592                 return;
 593         }
 594 
 595         /* Did we come from a system call? */
 596         if (in_syscall)
 597                 insert_restart_trampoline(regs);
 598         
 599         DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
 600                 regs->gr[28]);
 601 
 602         restore_saved_sigmask();
 603 }
 604 
 605 void do_notify_resume(struct pt_regs *regs, long in_syscall)
 606 {
 607         if (test_thread_flag(TIF_SIGPENDING))
 608                 do_signal(regs, in_syscall);
 609 
 610         if (test_thread_flag(TIF_NOTIFY_RESUME)) {
 611                 clear_thread_flag(TIF_NOTIFY_RESUME);
 612                 tracehook_notify_resume(regs);
 613         }
 614 }

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