~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/um/kernel/signal.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/um/kernel/signal.c (Version linux-6.12-rc7) and /arch/ppc/kernel/signal.c (Version linux-2.4.37.11)


  1 // SPDX-License-Identifier: GPL-2.0            << 
  2 /*                                                  1 /*
  3  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@ !!   2  *  linux/arch/ppc/kernel/signal.c
                                                   >>   3  *
                                                   >>   4  *  PowerPC version
                                                   >>   5  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
                                                   >>   6  *
                                                   >>   7  *  Derived from "arch/i386/kernel/signal.c"
                                                   >>   8  *    Copyright (C) 1991, 1992 Linus Torvalds
                                                   >>   9  *    1997-11-28  Modified for POSIX.1b signals by Richard Henderson
                                                   >>  10  *
                                                   >>  11  *  This program is free software; you can redistribute it and/or
                                                   >>  12  *  modify it under the terms of the GNU General Public License
                                                   >>  13  *  as published by the Free Software Foundation; either version
                                                   >>  14  *  2 of the License, or (at your option) any later version.
  4  */                                                15  */
  5                                                    16 
  6 #include <linux/module.h>                      << 
  7 #include <linux/ptrace.h>                      << 
  8 #include <linux/sched.h>                           17 #include <linux/sched.h>
  9 #include <linux/ftrace.h>                      !!  18 #include <linux/mm.h>
 10 #include <asm/siginfo.h>                       !!  19 #include <linux/smp.h>
 11 #include <asm/signal.h>                        !!  20 #include <linux/smp_lock.h>
 12 #include <asm/unistd.h>                        !!  21 #include <linux/kernel.h>
 13 #include <frame_kern.h>                        !!  22 #include <linux/signal.h>
 14 #include <kern_util.h>                         !!  23 #include <linux/errno.h>
 15 #include <os.h>                                !!  24 #include <linux/wait.h>
                                                   >>  25 #include <linux/ptrace.h>
                                                   >>  26 #include <linux/unistd.h>
                                                   >>  27 #include <linux/stddef.h>
                                                   >>  28 #include <linux/elf.h>
                                                   >>  29 #include <asm/ucontext.h>
                                                   >>  30 #include <asm/uaccess.h>
                                                   >>  31 #include <asm/pgtable.h>
                                                   >>  32 
                                                   >>  33 #define DEBUG_SIG 0
 16                                                    34 
 17 EXPORT_SYMBOL(block_signals);                  !!  35 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 18 EXPORT_SYMBOL(unblock_signals);                !!  36 
                                                   >>  37 #ifndef MIN
                                                   >>  38 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
                                                   >>  39 #endif
 19                                                    40 
 20 void block_signals_trace(void)                 !!  41 #define GP_REGS_SIZE    MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
                                                   >>  42 
                                                   >>  43 extern void syscall_direct_return(struct pt_regs *regs);
                                                   >>  44 
                                                   >>  45 int do_signal(sigset_t *oldset, struct pt_regs *regs);
                                                   >>  46 
                                                   >>  47 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
                                                   >>  48 {
                                                   >>  49         if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
                                                   >>  50                 return -EFAULT;
                                                   >>  51         if (from->si_code < 0)
                                                   >>  52                 return __copy_to_user(to, from, sizeof(siginfo_t));
                                                   >>  53         else {
                                                   >>  54                 int err;
                                                   >>  55 
                                                   >>  56                 /* If you change siginfo_t structure, please be sure
                                                   >>  57                    this code is fixed accordingly.
                                                   >>  58                    It should never copy any pad contained in the structure
                                                   >>  59                    to avoid security leaks, but must copy the generic
                                                   >>  60                    3 ints plus the relevant union member.  */
                                                   >>  61                 err = __put_user(from->si_signo, &to->si_signo);
                                                   >>  62                 err |= __put_user(from->si_errno, &to->si_errno);
                                                   >>  63                 err |= __put_user((short)from->si_code, &to->si_code);
                                                   >>  64                 /* First 32bits of unions are always present.  */
                                                   >>  65                 err |= __put_user(from->si_pid, &to->si_pid);
                                                   >>  66                 switch (from->si_code >> 16) {
                                                   >>  67                 case __SI_FAULT >> 16:
                                                   >>  68                         break;
                                                   >>  69                 case __SI_CHLD >> 16:
                                                   >>  70                         err |= __put_user(from->si_utime, &to->si_utime);
                                                   >>  71                         err |= __put_user(from->si_stime, &to->si_stime);
                                                   >>  72                         err |= __put_user(from->si_status, &to->si_status);
                                                   >>  73                 default:
                                                   >>  74                         err |= __put_user(from->si_uid, &to->si_uid);
                                                   >>  75                         break;
                                                   >>  76                 /* case __SI_RT: This is not generated by the kernel as of now.  */
                                                   >>  77                 }
                                                   >>  78                 return err;
                                                   >>  79         }
                                                   >>  80 }
                                                   >>  81 
                                                   >>  82 /*
                                                   >>  83  * Atomically swap in the new signal mask, and wait for a signal.
                                                   >>  84  */
                                                   >>  85 int
                                                   >>  86 sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
                                                   >>  87                struct pt_regs *regs)
 21 {                                                  88 {
 22         block_signals();                       !!  89         sigset_t saveset;
 23         if (current_thread_info())             !!  90 
 24                 trace_hardirqs_off();          !!  91         mask &= _BLOCKABLE;
                                                   >>  92         spin_lock_irq(&current->sigmask_lock);
                                                   >>  93         saveset = current->blocked;
                                                   >>  94         siginitset(&current->blocked, mask);
                                                   >>  95         recalc_sigpending(current);
                                                   >>  96         spin_unlock_irq(&current->sigmask_lock);
                                                   >>  97 
                                                   >>  98         regs->result = -EINTR;
                                                   >>  99         regs->gpr[3] = EINTR;
                                                   >> 100         regs->ccr |= 0x10000000;
                                                   >> 101         while (1) {
                                                   >> 102                 current->state = TASK_INTERRUPTIBLE;
                                                   >> 103                 schedule();
                                                   >> 104                 if (do_signal(&saveset, regs))
                                                   >> 105                         /*
                                                   >> 106                          * If a signal handler needs to be called,
                                                   >> 107                          * do_signal() has set R3 to the signal number (the
                                                   >> 108                          * first argument of the signal handler), so don't
                                                   >> 109                          * overwrite that with EINTR !
                                                   >> 110                          * In the other cases, do_signal() doesn't touch
                                                   >> 111                          * R3, so it's still set to -EINTR (see above).
                                                   >> 112                          */
                                                   >> 113                         return regs->gpr[3];
                                                   >> 114         }
 25 }                                                 115 }
 26                                                   116 
 27 void unblock_signals_trace(void)               !! 117 int
                                                   >> 118 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
                                                   >> 119                   int p7, struct pt_regs *regs)
 28 {                                                 120 {
 29         if (current_thread_info())             !! 121         sigset_t saveset, newset;
 30                 trace_hardirqs_on();           !! 122 
 31         unblock_signals();                     !! 123         /* XXX: Don't preclude handling different sized sigset_t's.  */
                                                   >> 124         if (sigsetsize != sizeof(sigset_t))
                                                   >> 125                 return -EINVAL;
                                                   >> 126 
                                                   >> 127         if (copy_from_user(&newset, unewset, sizeof(newset)))
                                                   >> 128                 return -EFAULT;
                                                   >> 129         sigdelsetmask(&newset, ~_BLOCKABLE);
                                                   >> 130 
                                                   >> 131         spin_lock_irq(&current->sigmask_lock);
                                                   >> 132         saveset = current->blocked;
                                                   >> 133         current->blocked = newset;
                                                   >> 134         recalc_sigpending(current);
                                                   >> 135         spin_unlock_irq(&current->sigmask_lock);
                                                   >> 136 
                                                   >> 137         regs->result = -EINTR;
                                                   >> 138         regs->gpr[3] = EINTR;
                                                   >> 139         regs->ccr |= 0x10000000;
                                                   >> 140         while (1) {
                                                   >> 141                 current->state = TASK_INTERRUPTIBLE;
                                                   >> 142                 schedule();
                                                   >> 143                 if (do_signal(&saveset, regs))
                                                   >> 144                         return regs->gpr[3];
                                                   >> 145         }
 32 }                                                 146 }
 33                                                   147 
 34 void um_trace_signals_on(void)                 !! 148 
                                                   >> 149 int
                                                   >> 150 sys_sigaltstack(const stack_t *uss, stack_t *uoss, int r5, int r6,
                                                   >> 151                 int r7, int r8, struct pt_regs *regs)
 35 {                                                 152 {
 36         if (current_thread_info())             !! 153         return do_sigaltstack(uss, uoss, regs->gpr[1]);
 37                 trace_hardirqs_on();           << 
 38 }                                                 154 }
 39                                                   155 
 40 void um_trace_signals_off(void)                !! 156 int
                                                   >> 157 sys_sigaction(int sig, const struct old_sigaction *act,
                                                   >> 158               struct old_sigaction *oact)
 41 {                                                 159 {
 42         if (current_thread_info())             !! 160         struct k_sigaction new_ka, old_ka;
 43                 trace_hardirqs_off();          !! 161         int ret;
                                                   >> 162 
                                                   >> 163         if (act) {
                                                   >> 164                 old_sigset_t mask;
                                                   >> 165                 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
                                                   >> 166                     __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
                                                   >> 167                     __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
                                                   >> 168                         return -EFAULT;
                                                   >> 169                 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
                                                   >> 170                 __get_user(mask, &act->sa_mask);
                                                   >> 171                 siginitset(&new_ka.sa.sa_mask, mask);
                                                   >> 172         }
                                                   >> 173 
                                                   >> 174         ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL));
                                                   >> 175 
                                                   >> 176         if (!ret && oact) {
                                                   >> 177                 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
                                                   >> 178                     __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
                                                   >> 179                     __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
                                                   >> 180                         return -EFAULT;
                                                   >> 181                 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
                                                   >> 182                 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
                                                   >> 183         }
                                                   >> 184 
                                                   >> 185         return ret;
 44 }                                                 186 }
 45                                                   187 
 46 /*                                                188 /*
 47  * OK, we're invoking a handler                !! 189  * When we have signals to deliver, we set up on the
                                                   >> 190  * user stack, going down from the original stack pointer:
                                                   >> 191  *      a sigregs struct
                                                   >> 192  *      a sigcontext struct
                                                   >> 193  *      a gap of __SIGNAL_FRAMESIZE bytes
                                                   >> 194  *
                                                   >> 195  * Each of these things must be a multiple of 16 bytes in size.
                                                   >> 196  *
                                                   >> 197  */
                                                   >> 198 struct sigregs {
                                                   >> 199         struct mcontext mctx;           /* all the register values */
                                                   >> 200         /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
                                                   >> 201            and 18 fp regs below sp before decrementing it. */
                                                   >> 202         int             abigap[56];
                                                   >> 203 };
                                                   >> 204 
                                                   >> 205 /* We use the mc_pad field for the signal return trampoline. */
                                                   >> 206 #define tramp   mc_pad
                                                   >> 207 
                                                   >> 208 /*
                                                   >> 209  *  When we have rt signals to deliver, we set up on the
                                                   >> 210  *  user stack, going down from the original stack pointer:
                                                   >> 211  *      one rt_sigframe struct (siginfo + ucontext + ABI gap)
                                                   >> 212  *      a gap of __SIGNAL_FRAMESIZE+16 bytes
                                                   >> 213  *  (the +16 is to get the siginfo and ucontext in the same
                                                   >> 214  *  positions as in older kernels).
                                                   >> 215  *
                                                   >> 216  *  Each of these things must be a multiple of 16 bytes in size.
                                                   >> 217  *
 48  */                                               218  */
 49 static void handle_signal(struct ksignal *ksig !! 219 struct rt_sigframe
 50 {                                                 220 {
 51         sigset_t *oldset = sigmask_to_save();  !! 221         struct siginfo info;
 52         int singlestep = 0;                    !! 222         struct ucontext uc;
 53         unsigned long sp;                      !! 223         /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
 54         int err;                               !! 224            and 18 fp regs below sp before decrementing it. */
 55                                                !! 225         int             abigap[56];
 56         if (test_thread_flag(TIF_SINGLESTEP) & !! 226 };
 57                 singlestep = 1;                << 
 58                                                << 
 59         /* Did we come from a system call? */  << 
 60         if (PT_REGS_SYSCALL_NR(regs) >= 0) {   << 
 61                 /* If so, check system call re << 
 62                 switch (PT_REGS_SYSCALL_RET(re << 
 63                 case -ERESTART_RESTARTBLOCK:   << 
 64                 case -ERESTARTNOHAND:          << 
 65                         PT_REGS_SYSCALL_RET(re << 
 66                         break;                 << 
 67                                                   227 
 68                 case -ERESTARTSYS:             !! 228 /*
 69                         if (!(ksig->ka.sa.sa_f !! 229  * Save the current user registers on the user stack.
 70                                 PT_REGS_SYSCAL !! 230  * We only save the altivec registers if the process has used
 71                                 break;         !! 231  * altivec instructions at some point.
 72                         }                      !! 232  */
 73                         fallthrough;           !! 233 static int
 74                 case -ERESTARTNOINTR:          !! 234 save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
 75                         PT_REGS_RESTART_SYSCAL !! 235 {
 76                         PT_REGS_ORIG_SYSCALL(r !! 236         /* save general and floating-point registers */
 77                         break;                 !! 237         if (regs->msr & MSR_FP)
 78                 }                              !! 238                 giveup_fpu(current);
                                                   >> 239         if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
                                                   >> 240             || __copy_to_user(&frame->mc_fregs, current->thread.fpr,
                                                   >> 241                               ELF_NFPREG * sizeof(double)))
                                                   >> 242                 return 1;
                                                   >> 243 
                                                   >> 244         current->thread.fpscr = 0;      /* turn off all fp exceptions */
                                                   >> 245 
                                                   >> 246 #ifdef CONFIG_ALTIVEC
                                                   >> 247         /* save altivec registers */
                                                   >> 248         if (current->thread.used_vr) {
                                                   >> 249                 if (regs->msr & MSR_VEC)
                                                   >> 250                         giveup_altivec(current);
                                                   >> 251                 if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
                                                   >> 252                                    ELF_NVRREG * sizeof(vector128)))
                                                   >> 253                         return 1;
                                                   >> 254                 /* set MSR_VEC in the saved MSR value to indicate that
                                                   >> 255                    frame->mc_vregs contains valid data */
                                                   >> 256                 if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
                                                   >> 257                         return 1;
 79         }                                         258         }
                                                   >> 259         /* else assert((regs->msr & MSR_VEC) == 0) */
 80                                                   260 
 81         sp = PT_REGS_SP(regs);                 !! 261         /* We always copy to/from vrsave, it's 0 if we don't have or don't
 82         if ((ksig->ka.sa.sa_flags & SA_ONSTACK !! 262          * use altivec. Since VSCR only contains 32 bits saved in the least
 83                 sp = current->sas_ss_sp + curr !! 263          * significant bits of a vector, we "cheat" and stuff VRSAVE in the
 84                                                !! 264          * most significant bits of that same vector. --BenH
 85 #ifdef CONFIG_ARCH_HAS_SC_SIGNALS              !! 265          */
 86         if (!(ksig->ka.sa.sa_flags & SA_SIGINF !! 266         if (__put_user(current->thread.vrsave, (u32 *)&frame->mc_vregs[32]))
 87                 err = setup_signal_stack_sc(sp !! 267                 return 1;
 88         else                                   !! 268 #endif /* CONFIG_ALTIVEC */
                                                   >> 269 
                                                   >> 270         if (sigret) {
                                                   >> 271                 /* Set up the sigreturn trampoline: li r0,sigret; sc */
                                                   >> 272                 if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
                                                   >> 273                     || __put_user(0x44000002UL, &frame->tramp[1]))
                                                   >> 274                         return 1;
                                                   >> 275                 flush_icache_range((unsigned long) &frame->tramp[0],
                                                   >> 276                                    (unsigned long) &frame->tramp[2]);
                                                   >> 277         }
                                                   >> 278 
                                                   >> 279         return 0;
                                                   >> 280 }
                                                   >> 281 
                                                   >> 282 /*
                                                   >> 283  * Restore the current user register values from the user stack,
                                                   >> 284  * (except for MSR).
                                                   >> 285  */
                                                   >> 286 static int
                                                   >> 287 restore_user_regs(struct pt_regs *regs, struct mcontext *sr)
                                                   >> 288 {
                                                   >> 289 #ifdef CONFIG_ALTIVEC
                                                   >> 290         unsigned long msr;
 89 #endif                                            291 #endif
 90                 err = setup_signal_stack_si(sp << 
 91                                                   292 
 92         signal_setup_done(err, ksig, singleste !! 293         /* copy up to but not including MSR */
                                                   >> 294         if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t)))
                                                   >> 295                 return 1;
                                                   >> 296         /* copy from orig_r3 (the word after the MSR) up to the end */
                                                   >> 297         if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
                                                   >> 298                              GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
                                                   >> 299                 return 1;
                                                   >> 300 
                                                   >> 301         /* force the process to reload the FP registers from
                                                   >> 302            current->thread when it next does FP instructions */
                                                   >> 303         regs->msr &= ~MSR_FP;
                                                   >> 304         if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
                                                   >> 305                              sizeof(sr->mc_fregs)))
                                                   >> 306                 return 1;
                                                   >> 307 
                                                   >> 308 #ifdef CONFIG_ALTIVEC
                                                   >> 309         /* force the process to reload the altivec registers from
                                                   >> 310            current->thread when it next does altivec instructions */
                                                   >> 311         regs->msr &= ~MSR_VEC;
                                                   >> 312         if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
                                                   >> 313                 /* restore altivec registers from the stack */
                                                   >> 314                 if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
                                                   >> 315                                      sizeof(sr->mc_vregs)))
                                                   >> 316                         return 1;
                                                   >> 317         } else if (current->thread.used_vr)
                                                   >> 318                 memset(&current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
                                                   >> 319 
                                                   >> 320         /* Always get VRSAVE back */
                                                   >> 321         if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32]))
                                                   >> 322                 return 1;
                                                   >> 323 #endif /* CONFIG_ALTIVEC */
                                                   >> 324 
                                                   >> 325         return 0;
 93 }                                                 326 }
 94                                                   327 
 95 void do_signal(struct pt_regs *regs)           !! 328 /*
                                                   >> 329  * Restore the user process's signal mask
                                                   >> 330  */
                                                   >> 331 static void
                                                   >> 332 restore_sigmask(sigset_t *set)
 96 {                                                 333 {
 97         struct ksignal ksig;                   !! 334         sigdelsetmask(set, ~_BLOCKABLE);
 98         int handled_sig = 0;                   !! 335         spin_lock_irq(&current->sigmask_lock);
                                                   >> 336         current->blocked = *set;
                                                   >> 337         recalc_sigpending(current);
                                                   >> 338         spin_unlock_irq(&current->sigmask_lock);
                                                   >> 339 }
                                                   >> 340 
                                                   >> 341 /*
                                                   >> 342  * Set up a signal frame for a "real-time" signal handler
                                                   >> 343  * (one which gets siginfo).
                                                   >> 344  */
                                                   >> 345 static void
                                                   >> 346 handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
                                                   >> 347                  siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
                                                   >> 348                  unsigned long newsp)
                                                   >> 349 {
                                                   >> 350         struct rt_sigframe *rt_sf;
                                                   >> 351         struct mcontext *frame;
                                                   >> 352         unsigned long origsp = newsp;
                                                   >> 353 
                                                   >> 354         /* Set up Signal Frame */
                                                   >> 355         /* Put a Real Time Context onto stack */
                                                   >> 356         newsp -= sizeof(*rt_sf);
                                                   >> 357         rt_sf = (struct rt_sigframe *) newsp;
                                                   >> 358 
                                                   >> 359         /* create a stack frame for the caller of the handler */
                                                   >> 360         newsp -= __SIGNAL_FRAMESIZE + 16;
                                                   >> 361 
                                                   >> 362         if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp))
                                                   >> 363                 goto badframe;
                                                   >> 364 
                                                   >> 365         /* Put the siginfo & fill in most of the ucontext */
                                                   >> 366         if (__copy_to_user(&rt_sf->info, info, sizeof(*info))
                                                   >> 367             || __put_user(0, &rt_sf->uc.uc_flags)
                                                   >> 368             || __put_user(0, &rt_sf->uc.uc_link)
                                                   >> 369             || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
                                                   >> 370             || __put_user(sas_ss_flags(regs->gpr[1]), 
                                                   >> 371                           &rt_sf->uc.uc_stack.ss_flags)
                                                   >> 372             || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
                                                   >> 373             || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
                                                   >> 374             || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
                                                   >> 375                 goto badframe;
                                                   >> 376 
                                                   >> 377         /* Save user registers on the stack */
                                                   >> 378         frame = &rt_sf->uc.uc_mcontext;
                                                   >> 379         if (save_user_regs(regs, frame, 0x6666))
                                                   >> 380                 goto badframe;
                                                   >> 381 
                                                   >> 382         if (put_user(regs->gpr[1], (unsigned long *)newsp))
                                                   >> 383                 goto badframe;
                                                   >> 384         regs->gpr[1] = newsp;
                                                   >> 385         regs->gpr[3] = sig;
                                                   >> 386         regs->gpr[4] = (unsigned long) &rt_sf->info;
                                                   >> 387         regs->gpr[5] = (unsigned long) &rt_sf->uc;
                                                   >> 388         regs->gpr[6] = (unsigned long) rt_sf;
                                                   >> 389         regs->nip = (unsigned long) ka->sa.sa_handler;
                                                   >> 390         regs->link = (unsigned long) frame->tramp;
                                                   >> 391 
                                                   >> 392         return;
                                                   >> 393 
                                                   >> 394 badframe:
                                                   >> 395 #if DEBUG_SIG
                                                   >> 396         printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
                                                   >> 397                regs, frame, newsp);
                                                   >> 398 #endif
                                                   >> 399         if (sig == SIGSEGV)
                                                   >> 400                 ka->sa.sa_handler = SIG_DFL;
                                                   >> 401         force_sig(SIGSEGV, current);
                                                   >> 402 }
                                                   >> 403 
                                                   >> 404 static int do_setcontext(struct ucontext *ucp, struct pt_regs *regs)
                                                   >> 405 {
                                                   >> 406         sigset_t set;
                                                   >> 407         struct mcontext *mcp;
                                                   >> 408 
                                                   >> 409         if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set))
                                                   >> 410             || __get_user(mcp, &ucp->uc_regs))
                                                   >> 411                 return -EFAULT;
                                                   >> 412         restore_sigmask(&set);
                                                   >> 413         if (restore_user_regs(regs, mcp))
                                                   >> 414                 return -EFAULT;
                                                   >> 415 
                                                   >> 416         return 0;
                                                   >> 417 }
 99                                                   418 
100         while (get_signal(&ksig)) {            !! 419 int sys_swapcontext(struct ucontext *old_ctx, struct ucontext *new_ctx,
101                 handled_sig = 1;               !! 420                     int r5, int r6, int r7, int r8, struct pt_regs *regs)
102                 /* Whee!  Actually deliver the !! 421 {
103                 handle_signal(&ksig, regs);    !! 422         unsigned char tmp;
                                                   >> 423 
                                                   >> 424         if (old_ctx != NULL) {
                                                   >> 425                 if (verify_area(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
                                                   >> 426                     || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
                                                   >> 427                     || __copy_to_user(&old_ctx->uc_sigmask,
                                                   >> 428                                       &current->blocked, sizeof(sigset_t))
                                                   >> 429                     || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
                                                   >> 430                         return -EFAULT;
104         }                                         431         }
                                                   >> 432         if (new_ctx == NULL)
                                                   >> 433                 return 0;
                                                   >> 434         if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx))
                                                   >> 435             || __get_user(tmp, (u8 *) new_ctx)
                                                   >> 436             || __get_user(tmp, (u8 *) (new_ctx + 1) - 1))
                                                   >> 437                 return -EFAULT;
105                                                   438 
106         /* Did we come from a system call? */  !! 439         /*
107         if (!handled_sig && (PT_REGS_SYSCALL_N !! 440          * If we get a fault copying the context into the kernel's
108                 /* Restart the system call - n !! 441          * image of the user's registers, we can't just return -EFAULT
109                 switch (PT_REGS_SYSCALL_RET(re !! 442          * because the user's registers will be corrupted.  For instance
110                 case -ERESTARTNOHAND:          !! 443          * the NIP value may have been updated but not some of the
                                                   >> 444          * other registers.  Given that we have done the verify_area
                                                   >> 445          * and successfully read the first and last bytes of the region
                                                   >> 446          * above, this should only happen in an out-of-memory situation
                                                   >> 447          * or if another thread unmaps the region containing the context.
                                                   >> 448          * We kill the task with a SIGSEGV in this situation.
                                                   >> 449          */
                                                   >> 450         if (do_setcontext(new_ctx, regs))
                                                   >> 451                 do_exit(SIGSEGV);
                                                   >> 452         syscall_direct_return(regs);
                                                   >> 453         /* doesn't actually return back to here */
                                                   >> 454         return 0;
                                                   >> 455 }
                                                   >> 456 
                                                   >> 457 int sys_rt_sigreturn(struct pt_regs *regs)
                                                   >> 458 {
                                                   >> 459         struct rt_sigframe *rt_sf;
                                                   >> 460         stack_t st;
                                                   >> 461 
                                                   >> 462         rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
                                                   >> 463         if (verify_area(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
                                                   >> 464                 goto bad;
                                                   >> 465         if (do_setcontext(&rt_sf->uc, regs))
                                                   >> 466                 goto bad;
                                                   >> 467 
                                                   >> 468         /*
                                                   >> 469          * It's not clear whether or why it is desirable to save the
                                                   >> 470          * sigaltstack setting on signal delivery and restore it on
                                                   >> 471          * signal return.  But other architectures do this and we have
                                                   >> 472          * always done it up until now so it is probably better not to
                                                   >> 473          * change it.  -- paulus
                                                   >> 474          */
                                                   >> 475         if (__copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
                                                   >> 476                 goto bad;
                                                   >> 477         do_sigaltstack(&st, NULL, regs->gpr[1]);
                                                   >> 478 
                                                   >> 479         return regs->result;
                                                   >> 480 
                                                   >> 481  bad:
                                                   >> 482         force_sig(SIGSEGV, current);
                                                   >> 483         return 0;
                                                   >> 484 }
                                                   >> 485 
                                                   >> 486 /*
                                                   >> 487  * OK, we're invoking a handler
                                                   >> 488  */
                                                   >> 489 static void
                                                   >> 490 handle_signal(unsigned long sig, struct k_sigaction *ka,
                                                   >> 491               siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
                                                   >> 492               unsigned long newsp)
                                                   >> 493 {
                                                   >> 494         struct sigcontext *sc;
                                                   >> 495         struct sigregs *frame;
                                                   >> 496         unsigned long origsp = newsp;
                                                   >> 497 
                                                   >> 498         /* Set up Signal Frame */
                                                   >> 499         newsp -= sizeof(struct sigregs);
                                                   >> 500         frame = (struct sigregs *) newsp;
                                                   >> 501 
                                                   >> 502         /* Put a sigcontext on the stack */
                                                   >> 503         newsp -= sizeof(*sc);
                                                   >> 504         sc = (struct sigcontext *) newsp;
                                                   >> 505 
                                                   >> 506         /* create a stack frame for the caller of the handler */
                                                   >> 507         newsp -= __SIGNAL_FRAMESIZE;
                                                   >> 508 
                                                   >> 509         if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp))
                                                   >> 510                 goto badframe;
                                                   >> 511 
                                                   >> 512 #if _NSIG != 64
                                                   >> 513 #error "Please adjust handle_signal()"
                                                   >> 514 #endif
                                                   >> 515         if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
                                                   >> 516             || __put_user(oldset->sig[0], &sc->oldmask)
                                                   >> 517             || __put_user(oldset->sig[1], &sc->_unused[3])
                                                   >> 518             || __put_user((struct pt_regs *)frame, &sc->regs)
                                                   >> 519             || __put_user(sig, &sc->signal))
                                                   >> 520                 goto badframe;
                                                   >> 521 
                                                   >> 522         if (save_user_regs(regs, &frame->mctx, 0x7777))
                                                   >> 523                 goto badframe;
                                                   >> 524 
                                                   >> 525         if (put_user(regs->gpr[1], (unsigned long *)newsp))
                                                   >> 526                 goto badframe;
                                                   >> 527         regs->gpr[1] = newsp;
                                                   >> 528         regs->gpr[3] = sig;
                                                   >> 529         regs->gpr[4] = (unsigned long) sc;
                                                   >> 530         regs->nip = (unsigned long) ka->sa.sa_handler;
                                                   >> 531         regs->link = (unsigned long) frame->mctx.tramp;
                                                   >> 532 
                                                   >> 533         return;
                                                   >> 534 
                                                   >> 535 badframe:
                                                   >> 536 #if DEBUG_SIG
                                                   >> 537         printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
                                                   >> 538                regs, frame, *newspp);
                                                   >> 539 #endif
                                                   >> 540         if (sig == SIGSEGV)
                                                   >> 541                 ka->sa.sa_handler = SIG_DFL;
                                                   >> 542         force_sig(SIGSEGV, current);
                                                   >> 543 }
                                                   >> 544 
                                                   >> 545 /*
                                                   >> 546  * Do a signal return; undo the signal stack.
                                                   >> 547  */
                                                   >> 548 int sys_sigreturn(struct pt_regs *regs)
                                                   >> 549 {
                                                   >> 550         struct sigcontext *sc, sigctx;
                                                   >> 551         struct mcontext *sr;
                                                   >> 552         int ret;
                                                   >> 553         sigset_t set;
                                                   >> 554 
                                                   >> 555         sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
                                                   >> 556         if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
                                                   >> 557                 goto badframe;
                                                   >> 558 
                                                   >> 559         set.sig[0] = sigctx.oldmask;
                                                   >> 560         set.sig[1] = sigctx._unused[3];
                                                   >> 561         restore_sigmask(&set);
                                                   >> 562 
                                                   >> 563         sr = (struct mcontext *) sigctx.regs;
                                                   >> 564         if (verify_area(VERIFY_READ, sr, sizeof(*sr))
                                                   >> 565             || restore_user_regs(regs, sr))
                                                   >> 566                 goto badframe;
                                                   >> 567 
                                                   >> 568         ret = regs->result;
                                                   >> 569 
                                                   >> 570         return ret;
                                                   >> 571 
                                                   >> 572 badframe:
                                                   >> 573         force_sig(SIGSEGV, current);
                                                   >> 574         return 0;
                                                   >> 575 }       
                                                   >> 576 
                                                   >> 577 static int get_signal_to_deliver(struct siginfo *infop, struct pt_regs *regs)
                                                   >> 578 {
                                                   >> 579         struct k_sigaction *ka;
                                                   >> 580         int signr;
                                                   >> 581 
                                                   >> 582         for (;;) {
                                                   >> 583                 spin_lock_irq(&current->sigmask_lock);
                                                   >> 584                 signr = dequeue_signal(&current->blocked, infop);
                                                   >> 585                 spin_unlock_irq(&current->sigmask_lock);
                                                   >> 586 
                                                   >> 587                 if (!signr)
                                                   >> 588                         return 0;
                                                   >> 589 
                                                   >> 590                 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
                                                   >> 591                         /* Let the debugger run.  */
                                                   >> 592                         current->exit_code = signr;
                                                   >> 593                         current->state = TASK_STOPPED;
                                                   >> 594                         notify_parent(current, SIGCHLD);
                                                   >> 595                         schedule();
                                                   >> 596 
                                                   >> 597                         /* We're back.  Did the debugger cancel the sig?  */
                                                   >> 598                         if (!(signr = current->exit_code))
                                                   >> 599                                 continue;
                                                   >> 600                         current->exit_code = 0;
                                                   >> 601 
                                                   >> 602                         /* The debugger continued.  Ignore SIGSTOP.  */
                                                   >> 603                         if (signr == SIGSTOP)
                                                   >> 604                                 continue;
                                                   >> 605 
                                                   >> 606                         /* Update the siginfo structure.  Is this good?  */
                                                   >> 607                         if (signr != infop->si_signo) {
                                                   >> 608                                 infop->si_signo = signr;
                                                   >> 609                                 infop->si_errno = 0;
                                                   >> 610                                 infop->si_code = SI_USER;
                                                   >> 611                                 infop->si_pid = current->p_pptr->pid;
                                                   >> 612                                 infop->si_uid = current->p_pptr->uid;
                                                   >> 613                         }
                                                   >> 614 
                                                   >> 615                         /* If the (new) signal is now blocked, requeue it.  */
                                                   >> 616                         if (sigismember(&current->blocked, signr)) {
                                                   >> 617                                 send_sig_info(signr, infop, current);
                                                   >> 618                                 continue;
                                                   >> 619                         }
                                                   >> 620                 }
                                                   >> 621 
                                                   >> 622                 ka = &current->sig->action[signr-1];
                                                   >> 623                 if (ka->sa.sa_handler == SIG_IGN) {
                                                   >> 624                         if (signr != SIGCHLD)
                                                   >> 625                                 continue;
                                                   >> 626                         /* Check for SIGCHLD: it's special.  */
                                                   >> 627                         while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
                                                   >> 628                                 /* nothing */;
                                                   >> 629                         continue;
                                                   >> 630                 }
                                                   >> 631 
                                                   >> 632                 if (ka->sa.sa_handler == SIG_DFL) {
                                                   >> 633                         int exit_code = signr;
                                                   >> 634 
                                                   >> 635                         /* Init gets no signals it doesn't want.  */
                                                   >> 636                         if (current->pid == 1)
                                                   >> 637                                 continue;
                                                   >> 638 
                                                   >> 639                         switch (signr) {
                                                   >> 640                         case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
                                                   >> 641                                 continue;
                                                   >> 642 
                                                   >> 643                         case SIGTSTP: case SIGTTIN: case SIGTTOU:
                                                   >> 644                                 if (is_orphaned_pgrp(current->pgrp))
                                                   >> 645                                         continue;
                                                   >> 646                                 /* FALLTHRU */
                                                   >> 647 
                                                   >> 648                         case SIGSTOP:
                                                   >> 649                                 current->state = TASK_STOPPED;
                                                   >> 650                                 current->exit_code = signr;
                                                   >> 651                                 if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
                                                   >> 652                                         notify_parent(current, SIGCHLD);
                                                   >> 653                                 schedule();
                                                   >> 654                                 continue;
                                                   >> 655 
                                                   >> 656                         case SIGQUIT: case SIGILL: case SIGTRAP:
                                                   >> 657                         case SIGABRT: case SIGFPE: case SIGSEGV:
                                                   >> 658                         case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
                                                   >> 659                                 if (do_coredump(signr, regs))
                                                   >> 660                                         exit_code |= 0x80;
                                                   >> 661                                 /* FALLTHRU */
                                                   >> 662 
                                                   >> 663                         default:
                                                   >> 664                                 sig_exit(signr, exit_code, infop);
                                                   >> 665                                 /* NOTREACHED */
                                                   >> 666                         }
                                                   >> 667                 }
                                                   >> 668                 return signr;
                                                   >> 669         }
                                                   >> 670 }
                                                   >> 671 
                                                   >> 672 /*
                                                   >> 673  * Note that 'init' is a special process: it doesn't get signals it doesn't
                                                   >> 674  * want to handle. Thus you cannot kill init even with a SIGKILL even by
                                                   >> 675  * mistake.
                                                   >> 676  */
                                                   >> 677 int do_signal(sigset_t *oldset, struct pt_regs *regs)
                                                   >> 678 {
                                                   >> 679         siginfo_t info;
                                                   >> 680         struct k_sigaction *ka;
                                                   >> 681         unsigned long frame, newsp;
                                                   >> 682         int signr;
                                                   >> 683 
                                                   >> 684         if (!oldset)
                                                   >> 685                 oldset = &current->blocked;
                                                   >> 686 
                                                   >> 687         newsp = frame = 0;
                                                   >> 688 
                                                   >> 689         signr = get_signal_to_deliver(&info, regs);
                                                   >> 690 
                                                   >> 691         ka = (signr == 0)? NULL: &current->sig->action[signr-1];
                                                   >> 692 
                                                   >> 693         if (regs->trap == 0xc00) {              /* system call */
                                                   >> 694                 switch ((int) regs->result) {
111                 case -ERESTARTSYS:                695                 case -ERESTARTSYS:
                                                   >> 696                         if (signr == 0 || (ka->sa.sa_flags & SA_RESTART))
                                                   >> 697                                 goto retry;
                                                   >> 698                         /* fall through */
                                                   >> 699                 case -ERESTARTNOHAND:
                                                   >> 700                         if (signr > 0) {
                                                   >> 701                                 /* make the system call return an EINTR */
                                                   >> 702                                 regs->result = -EINTR;
                                                   >> 703                                 break;
                                                   >> 704                         }
                                                   >> 705                         /* fall through */
112                 case -ERESTARTNOINTR:             706                 case -ERESTARTNOINTR:
113                         PT_REGS_ORIG_SYSCALL(r !! 707                 retry:
114                         PT_REGS_RESTART_SYSCAL !! 708                         /* Back up & retry system call */
115                         break;                 !! 709                         regs->gpr[3] = regs->orig_gpr3;
116                 case -ERESTART_RESTARTBLOCK:   !! 710                         regs->nip -= 4;
117                         PT_REGS_ORIG_SYSCALL(r !! 711                         regs->result = 0;
118                         PT_REGS_RESTART_SYSCAL << 
119                         break;                    712                         break;
120                 }                                 713                 }
121         }                                         714         }
122                                                   715 
123         /*                                     !! 716         if (signr == 0)
124          * if there's no signal to deliver, we !! 717                 return 0;               /* no signals delivered */
125          * back                                !! 718 
126          */                                    !! 719         if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
127         if (!handled_sig)                      !! 720             && !on_sig_stack(regs->gpr[1]))
128                 restore_saved_sigmask();       !! 721                 newsp = current->sas_ss_sp + current->sas_ss_size;
                                                   >> 722         else
                                                   >> 723                 newsp = regs->gpr[1];
                                                   >> 724         newsp &= ~0xfUL;
                                                   >> 725 
                                                   >> 726         /* Whee!  Actually deliver the signal.  */
                                                   >> 727         if (ka->sa.sa_flags & SA_SIGINFO)
                                                   >> 728                 handle_rt_signal(signr, ka, &info, oldset, regs, newsp);
                                                   >> 729         else
                                                   >> 730                 handle_signal(signr, ka, &info, oldset, regs, newsp);
                                                   >> 731 
                                                   >> 732         if (ka->sa.sa_flags & SA_ONESHOT)
                                                   >> 733                 ka->sa.sa_handler = SIG_DFL;
                                                   >> 734 
                                                   >> 735         if (!(ka->sa.sa_flags & SA_NODEFER)) {
                                                   >> 736                 spin_lock_irq(&current->sigmask_lock);
                                                   >> 737                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
                                                   >> 738                 sigaddset(&current->blocked, signr);
                                                   >> 739                 recalc_sigpending(current);
                                                   >> 740                 spin_unlock_irq(&current->sigmask_lock);
                                                   >> 741         }
                                                   >> 742 
                                                   >> 743         return 1;
129 }                                                 744 }
                                                   >> 745 
130                                                   746 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php