~ [ 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.6.0)


  1 // SPDX-License-Identifier: GPL-2.0            << 
  2 /*                                                  1 /*
  3  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@ !!   2  *  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 <linux/tty.h>
                                                   >>  30 #include <linux/binfmts.h>
                                                   >>  31 #include <asm/ucontext.h>
                                                   >>  32 #include <asm/uaccess.h>
                                                   >>  33 #include <asm/pgtable.h>
                                                   >>  34 #include <asm/cacheflush.h>
                                                   >>  35 
                                                   >>  36 #define DEBUG_SIG 0
                                                   >>  37 
                                                   >>  38 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 16                                                    39 
 17 EXPORT_SYMBOL(block_signals);                  !!  40 extern void sigreturn_exit(struct pt_regs *);
 18 EXPORT_SYMBOL(unblock_signals);                << 
 19                                                    41 
 20 void block_signals_trace(void)                 !!  42 #define GP_REGS_SIZE    min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
                                                   >>  43 
                                                   >>  44 int do_signal(sigset_t *oldset, struct pt_regs *regs);
                                                   >>  45 
                                                   >>  46 /*
                                                   >>  47  * Atomically swap in the new signal mask, and wait for a signal.
                                                   >>  48  */
                                                   >>  49 int
                                                   >>  50 sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
                                                   >>  51                struct pt_regs *regs)
 21 {                                                  52 {
 22         block_signals();                       !!  53         sigset_t saveset;
 23         if (current_thread_info())             !!  54 
 24                 trace_hardirqs_off();          !!  55         mask &= _BLOCKABLE;
                                                   >>  56         spin_lock_irq(&current->sighand->siglock);
                                                   >>  57         saveset = current->blocked;
                                                   >>  58         siginitset(&current->blocked, mask);
                                                   >>  59         recalc_sigpending();
                                                   >>  60         spin_unlock_irq(&current->sighand->siglock);
                                                   >>  61 
                                                   >>  62         regs->result = -EINTR;
                                                   >>  63         regs->gpr[3] = EINTR;
                                                   >>  64         regs->ccr |= 0x10000000;
                                                   >>  65         while (1) {
                                                   >>  66                 current->state = TASK_INTERRUPTIBLE;
                                                   >>  67                 schedule();
                                                   >>  68                 if (do_signal(&saveset, regs))
                                                   >>  69                         sigreturn_exit(regs);
                                                   >>  70         }
 25 }                                                  71 }
 26                                                    72 
 27 void unblock_signals_trace(void)               !!  73 int
                                                   >>  74 sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4,
                                                   >>  75                   int p6, int p7, struct pt_regs *regs)
 28 {                                                  76 {
 29         if (current_thread_info())             !!  77         sigset_t saveset, newset;
 30                 trace_hardirqs_on();           !!  78 
 31         unblock_signals();                     !!  79         /* XXX: Don't preclude handling different sized sigset_t's.  */
                                                   >>  80         if (sigsetsize != sizeof(sigset_t))
                                                   >>  81                 return -EINVAL;
                                                   >>  82 
                                                   >>  83         if (copy_from_user(&newset, unewset, sizeof(newset)))
                                                   >>  84                 return -EFAULT;
                                                   >>  85         sigdelsetmask(&newset, ~_BLOCKABLE);
                                                   >>  86 
                                                   >>  87         spin_lock_irq(&current->sighand->siglock);
                                                   >>  88         saveset = current->blocked;
                                                   >>  89         current->blocked = newset;
                                                   >>  90         recalc_sigpending();
                                                   >>  91         spin_unlock_irq(&current->sighand->siglock);
                                                   >>  92 
                                                   >>  93         regs->result = -EINTR;
                                                   >>  94         regs->gpr[3] = EINTR;
                                                   >>  95         regs->ccr |= 0x10000000;
                                                   >>  96         while (1) {
                                                   >>  97                 current->state = TASK_INTERRUPTIBLE;
                                                   >>  98                 schedule();
                                                   >>  99                 if (do_signal(&saveset, regs))
                                                   >> 100                         sigreturn_exit(regs);
                                                   >> 101         }
 32 }                                                 102 }
 33                                                   103 
 34 void um_trace_signals_on(void)                 !! 104 
                                                   >> 105 int
                                                   >> 106 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
                                                   >> 107                 int r6, int r7, int r8, struct pt_regs *regs)
 35 {                                                 108 {
 36         if (current_thread_info())             !! 109         return do_sigaltstack(uss, uoss, regs->gpr[1]);
 37                 trace_hardirqs_on();           << 
 38 }                                                 110 }
 39                                                   111 
 40 void um_trace_signals_off(void)                !! 112 int
                                                   >> 113 sys_sigaction(int sig, const struct old_sigaction __user *act,
                                                   >> 114               struct old_sigaction __user *oact)
 41 {                                                 115 {
 42         if (current_thread_info())             !! 116         struct k_sigaction new_ka, old_ka;
 43                 trace_hardirqs_off();          !! 117         int ret;
                                                   >> 118 
                                                   >> 119         if (act) {
                                                   >> 120                 old_sigset_t mask;
                                                   >> 121                 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
                                                   >> 122                     __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
                                                   >> 123                     __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
                                                   >> 124                         return -EFAULT;
                                                   >> 125                 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
                                                   >> 126                 __get_user(mask, &act->sa_mask);
                                                   >> 127                 siginitset(&new_ka.sa.sa_mask, mask);
                                                   >> 128         }
                                                   >> 129 
                                                   >> 130         ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL));
                                                   >> 131 
                                                   >> 132         if (!ret && oact) {
                                                   >> 133                 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
                                                   >> 134                     __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
                                                   >> 135                     __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
                                                   >> 136                         return -EFAULT;
                                                   >> 137                 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
                                                   >> 138                 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
                                                   >> 139         }
                                                   >> 140 
                                                   >> 141         return ret;
 44 }                                                 142 }
 45                                                   143 
 46 /*                                                144 /*
 47  * OK, we're invoking a handler                !! 145  * When we have signals to deliver, we set up on the
                                                   >> 146  * user stack, going down from the original stack pointer:
                                                   >> 147  *      a sigregs struct
                                                   >> 148  *      a sigcontext struct
                                                   >> 149  *      a gap of __SIGNAL_FRAMESIZE bytes
                                                   >> 150  *
                                                   >> 151  * Each of these things must be a multiple of 16 bytes in size.
                                                   >> 152  *
                                                   >> 153  */
                                                   >> 154 struct sigregs {
                                                   >> 155         struct mcontext mctx;           /* all the register values */
                                                   >> 156         /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
                                                   >> 157            and 18 fp regs below sp before decrementing it. */
                                                   >> 158         int             abigap[56];
                                                   >> 159 };
                                                   >> 160 
                                                   >> 161 /* We use the mc_pad field for the signal return trampoline. */
                                                   >> 162 #define tramp   mc_pad
                                                   >> 163 
                                                   >> 164 /*
                                                   >> 165  *  When we have rt signals to deliver, we set up on the
                                                   >> 166  *  user stack, going down from the original stack pointer:
                                                   >> 167  *      one rt_sigframe struct (siginfo + ucontext + ABI gap)
                                                   >> 168  *      a gap of __SIGNAL_FRAMESIZE+16 bytes
                                                   >> 169  *  (the +16 is to get the siginfo and ucontext in the same
                                                   >> 170  *  positions as in older kernels).
                                                   >> 171  *
                                                   >> 172  *  Each of these things must be a multiple of 16 bytes in size.
                                                   >> 173  *
 48  */                                               174  */
 49 static void handle_signal(struct ksignal *ksig !! 175 struct rt_sigframe
 50 {                                                 176 {
 51         sigset_t *oldset = sigmask_to_save();  !! 177         struct siginfo info;
 52         int singlestep = 0;                    !! 178         struct ucontext uc;
 53         unsigned long sp;                      !! 179         /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
 54         int err;                               !! 180            and 18 fp regs below sp before decrementing it. */
 55                                                !! 181         int             abigap[56];
 56         if (test_thread_flag(TIF_SINGLESTEP) & !! 182 };
 57                 singlestep = 1;                !! 183 
 58                                                !! 184 /*
 59         /* Did we come from a system call? */  !! 185  * Save the current user registers on the user stack.
 60         if (PT_REGS_SYSCALL_NR(regs) >= 0) {   !! 186  * We only save the altivec registers if the process has used
 61                 /* If so, check system call re !! 187  * altivec instructions at some point.
 62                 switch (PT_REGS_SYSCALL_RET(re !! 188  */
 63                 case -ERESTART_RESTARTBLOCK:   !! 189 static int
 64                 case -ERESTARTNOHAND:          !! 190 save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
 65                         PT_REGS_SYSCALL_RET(re !! 191 {
 66                         break;                 !! 192         /* save general and floating-point registers */
 67                                                !! 193         CHECK_FULL_REGS(regs);
 68                 case -ERESTARTSYS:             !! 194         if (regs->msr & MSR_FP)
 69                         if (!(ksig->ka.sa.sa_f !! 195                 giveup_fpu(current);
 70                                 PT_REGS_SYSCAL !! 196         if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
 71                                 break;         !! 197             || __copy_to_user(&frame->mc_fregs, current->thread.fpr,
 72                         }                      !! 198                               ELF_NFPREG * sizeof(double)))
 73                         fallthrough;           !! 199                 return 1;
 74                 case -ERESTARTNOINTR:          !! 200 
 75                         PT_REGS_RESTART_SYSCAL !! 201         current->thread.fpscr = 0;      /* turn off all fp exceptions */
 76                         PT_REGS_ORIG_SYSCALL(r !! 202 
 77                         break;                 !! 203 #ifdef CONFIG_ALTIVEC
 78                 }                              !! 204         /* save altivec registers */
                                                   >> 205         if (current->thread.used_vr) {
                                                   >> 206                 if (regs->msr & MSR_VEC)
                                                   >> 207                         giveup_altivec(current);
                                                   >> 208                 if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
                                                   >> 209                                    ELF_NVRREG * sizeof(vector128)))
                                                   >> 210                         return 1;
                                                   >> 211                 /* set MSR_VEC in the saved MSR value to indicate that
                                                   >> 212                    frame->mc_vregs contains valid data */
                                                   >> 213                 if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
                                                   >> 214                         return 1;
 79         }                                         215         }
                                                   >> 216         /* else assert((regs->msr & MSR_VEC) == 0) */
 80                                                   217 
 81         sp = PT_REGS_SP(regs);                 !! 218         /* 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 !! 219          * use altivec. Since VSCR only contains 32 bits saved in the least
 83                 sp = current->sas_ss_sp + curr !! 220          * significant bits of a vector, we "cheat" and stuff VRSAVE in the
 84                                                !! 221          * most significant bits of that same vector. --BenH
 85 #ifdef CONFIG_ARCH_HAS_SC_SIGNALS              !! 222          */
 86         if (!(ksig->ka.sa.sa_flags & SA_SIGINF !! 223         if (__put_user(current->thread.vrsave, (u32 *)&frame->mc_vregs[32]))
 87                 err = setup_signal_stack_sc(sp !! 224                 return 1;
 88         else                                   !! 225 #endif /* CONFIG_ALTIVEC */
                                                   >> 226 
                                                   >> 227         if (sigret) {
                                                   >> 228                 /* Set up the sigreturn trampoline: li r0,sigret; sc */
                                                   >> 229                 if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
                                                   >> 230                     || __put_user(0x44000002UL, &frame->tramp[1]))
                                                   >> 231                         return 1;
                                                   >> 232                 flush_icache_range((unsigned long) &frame->tramp[0],
                                                   >> 233                                    (unsigned long) &frame->tramp[2]);
                                                   >> 234         }
                                                   >> 235 
                                                   >> 236         return 0;
                                                   >> 237 }
                                                   >> 238 
                                                   >> 239 /*
                                                   >> 240  * Restore the current user register values from the user stack,
                                                   >> 241  * (except for MSR).
                                                   >> 242  */
                                                   >> 243 static int
                                                   >> 244 restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr)
                                                   >> 245 {
                                                   >> 246 #ifdef CONFIG_ALTIVEC
                                                   >> 247         unsigned long msr;
 89 #endif                                            248 #endif
 90                 err = setup_signal_stack_si(sp << 
 91                                                   249 
 92         signal_setup_done(err, ksig, singleste !! 250         /* copy up to but not including MSR */
                                                   >> 251         if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t)))
                                                   >> 252                 return 1;
                                                   >> 253         /* copy from orig_r3 (the word after the MSR) up to the end */
                                                   >> 254         if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
                                                   >> 255                              GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
                                                   >> 256                 return 1;
                                                   >> 257 
                                                   >> 258         /* force the process to reload the FP registers from
                                                   >> 259            current->thread when it next does FP instructions */
                                                   >> 260         regs->msr &= ~MSR_FP;
                                                   >> 261         if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
                                                   >> 262                              sizeof(sr->mc_fregs)))
                                                   >> 263                 return 1;
                                                   >> 264 
                                                   >> 265 #ifdef CONFIG_ALTIVEC
                                                   >> 266         /* force the process to reload the altivec registers from
                                                   >> 267            current->thread when it next does altivec instructions */
                                                   >> 268         regs->msr &= ~MSR_VEC;
                                                   >> 269         if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
                                                   >> 270                 /* restore altivec registers from the stack */
                                                   >> 271                 if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
                                                   >> 272                                      sizeof(sr->mc_vregs)))
                                                   >> 273                         return 1;
                                                   >> 274         } else if (current->thread.used_vr)
                                                   >> 275                 memset(&current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
                                                   >> 276 
                                                   >> 277         /* Always get VRSAVE back */
                                                   >> 278         if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32]))
                                                   >> 279                 return 1;
                                                   >> 280 #endif /* CONFIG_ALTIVEC */
                                                   >> 281 
                                                   >> 282         return 0;
 93 }                                                 283 }
 94                                                   284 
 95 void do_signal(struct pt_regs *regs)           !! 285 /*
                                                   >> 286  * Restore the user process's signal mask
                                                   >> 287  */
                                                   >> 288 static void
                                                   >> 289 restore_sigmask(sigset_t *set)
 96 {                                                 290 {
 97         struct ksignal ksig;                   !! 291         sigdelsetmask(set, ~_BLOCKABLE);
 98         int handled_sig = 0;                   !! 292         spin_lock_irq(&current->sighand->siglock);
 99                                                !! 293         current->blocked = *set;
100         while (get_signal(&ksig)) {            !! 294         recalc_sigpending();
101                 handled_sig = 1;               !! 295         spin_unlock_irq(&current->sighand->siglock);
102                 /* Whee!  Actually deliver the !! 296 }
103                 handle_signal(&ksig, regs);    !! 297 
104         }                                      !! 298 /*
105                                                !! 299  * Set up a signal frame for a "real-time" signal handler
106         /* Did we come from a system call? */  !! 300  * (one which gets siginfo).
107         if (!handled_sig && (PT_REGS_SYSCALL_N !! 301  */
108                 /* Restart the system call - n !! 302 static void
109                 switch (PT_REGS_SYSCALL_RET(re !! 303 handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
110                 case -ERESTARTNOHAND:          !! 304                  siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
111                 case -ERESTARTSYS:             !! 305                  unsigned long newsp)
112                 case -ERESTARTNOINTR:          !! 306 {
113                         PT_REGS_ORIG_SYSCALL(r !! 307         struct rt_sigframe __user *rt_sf;
114                         PT_REGS_RESTART_SYSCAL !! 308         struct mcontext __user *frame;
115                         break;                 !! 309         unsigned long origsp = newsp;
116                 case -ERESTART_RESTARTBLOCK:   !! 310 
117                         PT_REGS_ORIG_SYSCALL(r !! 311         /* Set up Signal Frame */
118                         PT_REGS_RESTART_SYSCAL !! 312         /* Put a Real Time Context onto stack */
119                         break;                 !! 313         newsp -= sizeof(*rt_sf);
120                 }                              !! 314         rt_sf = (struct rt_sigframe __user *) newsp;
                                                   >> 315 
                                                   >> 316         /* create a stack frame for the caller of the handler */
                                                   >> 317         newsp -= __SIGNAL_FRAMESIZE + 16;
                                                   >> 318 
                                                   >> 319         if (verify_area(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
                                                   >> 320                 goto badframe;
                                                   >> 321 
                                                   >> 322         /* Put the siginfo & fill in most of the ucontext */
                                                   >> 323         if (copy_siginfo_to_user(&rt_sf->info, info)
                                                   >> 324             || __put_user(0, &rt_sf->uc.uc_flags)
                                                   >> 325             || __put_user(0, &rt_sf->uc.uc_link)
                                                   >> 326             || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
                                                   >> 327             || __put_user(sas_ss_flags(regs->gpr[1]),
                                                   >> 328                           &rt_sf->uc.uc_stack.ss_flags)
                                                   >> 329             || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
                                                   >> 330             || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
                                                   >> 331             || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
                                                   >> 332                 goto badframe;
                                                   >> 333 
                                                   >> 334         /* Save user registers on the stack */
                                                   >> 335         frame = &rt_sf->uc.uc_mcontext;
                                                   >> 336         if (save_user_regs(regs, frame, __NR_rt_sigreturn))
                                                   >> 337                 goto badframe;
                                                   >> 338 
                                                   >> 339         if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
                                                   >> 340                 goto badframe;
                                                   >> 341         regs->gpr[1] = newsp;
                                                   >> 342         regs->gpr[3] = sig;
                                                   >> 343         regs->gpr[4] = (unsigned long) &rt_sf->info;
                                                   >> 344         regs->gpr[5] = (unsigned long) &rt_sf->uc;
                                                   >> 345         regs->gpr[6] = (unsigned long) rt_sf;
                                                   >> 346         regs->nip = (unsigned long) ka->sa.sa_handler;
                                                   >> 347         regs->link = (unsigned long) frame->tramp;
                                                   >> 348         regs->trap = 0;
                                                   >> 349 
                                                   >> 350         return;
                                                   >> 351 
                                                   >> 352 badframe:
                                                   >> 353 #if DEBUG_SIG
                                                   >> 354         printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
                                                   >> 355                regs, frame, newsp);
                                                   >> 356 #endif
                                                   >> 357         if (sig == SIGSEGV)
                                                   >> 358                 ka->sa.sa_handler = SIG_DFL;
                                                   >> 359         force_sig(SIGSEGV, current);
                                                   >> 360 }
                                                   >> 361 
                                                   >> 362 static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs)
                                                   >> 363 {
                                                   >> 364         sigset_t set;
                                                   >> 365         struct mcontext *mcp;
                                                   >> 366 
                                                   >> 367         if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set))
                                                   >> 368             || __get_user(mcp, &ucp->uc_regs))
                                                   >> 369                 return -EFAULT;
                                                   >> 370         restore_sigmask(&set);
                                                   >> 371         if (restore_user_regs(regs, mcp))
                                                   >> 372                 return -EFAULT;
                                                   >> 373 
                                                   >> 374         return 0;
                                                   >> 375 }
                                                   >> 376 
                                                   >> 377 int sys_swapcontext(struct ucontext __user *old_ctx,
                                                   >> 378                     struct ucontext __user *new_ctx,
                                                   >> 379                     int r5, int r6, int r7, int r8, struct pt_regs *regs)
                                                   >> 380 {
                                                   >> 381         unsigned char tmp;
                                                   >> 382 
                                                   >> 383         if (old_ctx != NULL) {
                                                   >> 384                 if (verify_area(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
                                                   >> 385                     || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
                                                   >> 386                     || __copy_to_user(&old_ctx->uc_sigmask,
                                                   >> 387                                       &current->blocked, sizeof(sigset_t))
                                                   >> 388                     || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
                                                   >> 389                         return -EFAULT;
121         }                                         390         }
                                                   >> 391         if (new_ctx == NULL)
                                                   >> 392                 return 0;
                                                   >> 393         if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx))
                                                   >> 394             || __get_user(tmp, (u8 *) new_ctx)
                                                   >> 395             || __get_user(tmp, (u8 *) (new_ctx + 1) - 1))
                                                   >> 396                 return -EFAULT;
122                                                   397 
123         /*                                        398         /*
124          * if there's no signal to deliver, we !! 399          * If we get a fault copying the context into the kernel's
125          * back                                !! 400          * image of the user's registers, we can't just return -EFAULT
                                                   >> 401          * because the user's registers will be corrupted.  For instance
                                                   >> 402          * the NIP value may have been updated but not some of the
                                                   >> 403          * other registers.  Given that we have done the verify_area
                                                   >> 404          * and successfully read the first and last bytes of the region
                                                   >> 405          * above, this should only happen in an out-of-memory situation
                                                   >> 406          * or if another thread unmaps the region containing the context.
                                                   >> 407          * We kill the task with a SIGSEGV in this situation.
126          */                                       408          */
127         if (!handled_sig)                      !! 409         if (do_setcontext(new_ctx, regs))
128                 restore_saved_sigmask();       !! 410                 do_exit(SIGSEGV);
                                                   >> 411         sigreturn_exit(regs);
                                                   >> 412         /* doesn't actually return back to here */
                                                   >> 413         return 0;
                                                   >> 414 }
                                                   >> 415 
                                                   >> 416 int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
                                                   >> 417                      struct pt_regs *regs)
                                                   >> 418 {
                                                   >> 419         struct rt_sigframe __user *rt_sf;
                                                   >> 420 
                                                   >> 421         /* Always make any pending restarted system calls return -EINTR */
                                                   >> 422         current_thread_info()->restart_block.fn = do_no_restart_syscall;
                                                   >> 423 
                                                   >> 424         rt_sf = (struct rt_sigframe __user *)
                                                   >> 425                 (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
                                                   >> 426         if (verify_area(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
                                                   >> 427                 goto bad;
                                                   >> 428         if (do_setcontext(&rt_sf->uc, regs))
                                                   >> 429                 goto bad;
                                                   >> 430 
                                                   >> 431         /*
                                                   >> 432          * It's not clear whether or why it is desirable to save the
                                                   >> 433          * sigaltstack setting on signal delivery and restore it on
                                                   >> 434          * signal return.  But other architectures do this and we have
                                                   >> 435          * always done it up until now so it is probably better not to
                                                   >> 436          * change it.  -- paulus
                                                   >> 437          */
                                                   >> 438         do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
                                                   >> 439 
                                                   >> 440         sigreturn_exit(regs);           /* doesn't return here */
                                                   >> 441         return 0;
                                                   >> 442 
                                                   >> 443  bad:
                                                   >> 444         force_sig(SIGSEGV, current);
                                                   >> 445         return 0;
                                                   >> 446 }
                                                   >> 447 
                                                   >> 448 /*
                                                   >> 449  * OK, we're invoking a handler
                                                   >> 450  */
                                                   >> 451 static void
                                                   >> 452 handle_signal(unsigned long sig, struct k_sigaction *ka,
                                                   >> 453               siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
                                                   >> 454               unsigned long newsp)
                                                   >> 455 {
                                                   >> 456         struct sigcontext __user *sc;
                                                   >> 457         struct sigregs __user *frame;
                                                   >> 458         unsigned long origsp = newsp;
                                                   >> 459 
                                                   >> 460         /* Set up Signal Frame */
                                                   >> 461         newsp -= sizeof(struct sigregs);
                                                   >> 462         frame = (struct sigregs __user *) newsp;
                                                   >> 463 
                                                   >> 464         /* Put a sigcontext on the stack */
                                                   >> 465         newsp -= sizeof(*sc);
                                                   >> 466         sc = (struct sigcontext __user *) newsp;
                                                   >> 467 
                                                   >> 468         /* create a stack frame for the caller of the handler */
                                                   >> 469         newsp -= __SIGNAL_FRAMESIZE;
                                                   >> 470 
                                                   >> 471         if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp))
                                                   >> 472                 goto badframe;
                                                   >> 473 
                                                   >> 474 #if _NSIG != 64
                                                   >> 475 #error "Please adjust handle_signal()"
                                                   >> 476 #endif
                                                   >> 477         if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
                                                   >> 478             || __put_user(oldset->sig[0], &sc->oldmask)
                                                   >> 479             || __put_user(oldset->sig[1], &sc->_unused[3])
                                                   >> 480             || __put_user((struct pt_regs *)frame, &sc->regs)
                                                   >> 481             || __put_user(sig, &sc->signal))
                                                   >> 482                 goto badframe;
                                                   >> 483 
                                                   >> 484         if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
                                                   >> 485                 goto badframe;
                                                   >> 486 
                                                   >> 487         if (put_user(regs->gpr[1], (unsigned long *)newsp))
                                                   >> 488                 goto badframe;
                                                   >> 489         regs->gpr[1] = newsp;
                                                   >> 490         regs->gpr[3] = sig;
                                                   >> 491         regs->gpr[4] = (unsigned long) sc;
                                                   >> 492         regs->nip = (unsigned long) ka->sa.sa_handler;
                                                   >> 493         regs->link = (unsigned long) frame->mctx.tramp;
                                                   >> 494         regs->trap = 0;
                                                   >> 495 
                                                   >> 496         return;
                                                   >> 497 
                                                   >> 498 badframe:
                                                   >> 499 #if DEBUG_SIG
                                                   >> 500         printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
                                                   >> 501                regs, frame, *newspp);
                                                   >> 502 #endif
                                                   >> 503         if (sig == SIGSEGV)
                                                   >> 504                 ka->sa.sa_handler = SIG_DFL;
                                                   >> 505         force_sig(SIGSEGV, current);
129 }                                                 506 }
                                                   >> 507 
                                                   >> 508 /*
                                                   >> 509  * Do a signal return; undo the signal stack.
                                                   >> 510  */
                                                   >> 511 int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
                                                   >> 512                   struct pt_regs *regs)
                                                   >> 513 {
                                                   >> 514         struct sigcontext __user *sc;
                                                   >> 515         struct sigcontext sigctx;
                                                   >> 516         struct mcontext __user *sr;
                                                   >> 517         sigset_t set;
                                                   >> 518 
                                                   >> 519         /* Always make any pending restarted system calls return -EINTR */
                                                   >> 520         current_thread_info()->restart_block.fn = do_no_restart_syscall;
                                                   >> 521 
                                                   >> 522         sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
                                                   >> 523         if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
                                                   >> 524                 goto badframe;
                                                   >> 525 
                                                   >> 526         set.sig[0] = sigctx.oldmask;
                                                   >> 527         set.sig[1] = sigctx._unused[3];
                                                   >> 528         restore_sigmask(&set);
                                                   >> 529 
                                                   >> 530         sr = (struct mcontext *) sigctx.regs;
                                                   >> 531         if (verify_area(VERIFY_READ, sr, sizeof(*sr))
                                                   >> 532             || restore_user_regs(regs, sr))
                                                   >> 533                 goto badframe;
                                                   >> 534 
                                                   >> 535         sigreturn_exit(regs);           /* doesn't return */
                                                   >> 536         return 0;
                                                   >> 537 
                                                   >> 538 badframe:
                                                   >> 539         force_sig(SIGSEGV, current);
                                                   >> 540         return 0;
                                                   >> 541 }
                                                   >> 542 
                                                   >> 543 /*
                                                   >> 544  * Note that 'init' is a special process: it doesn't get signals it doesn't
                                                   >> 545  * want to handle. Thus you cannot kill init even with a SIGKILL even by
                                                   >> 546  * mistake.
                                                   >> 547  */
                                                   >> 548 int do_signal(sigset_t *oldset, struct pt_regs *regs)
                                                   >> 549 {
                                                   >> 550         siginfo_t info;
                                                   >> 551         struct k_sigaction *ka;
                                                   >> 552         unsigned long frame, newsp;
                                                   >> 553         int signr, ret;
                                                   >> 554 
                                                   >> 555         if (!oldset)
                                                   >> 556                 oldset = &current->blocked;
                                                   >> 557 
                                                   >> 558         newsp = frame = 0;
                                                   >> 559 
                                                   >> 560         signr = get_signal_to_deliver(&info, regs, NULL);
                                                   >> 561 
                                                   >> 562         ka = (signr == 0)? NULL: &current->sighand->action[signr-1];
                                                   >> 563 
                                                   >> 564         if (TRAP(regs) == 0x0C00                /* System Call! */
                                                   >> 565             && regs->ccr & 0x10000000           /* error signalled */
                                                   >> 566             && ((ret = regs->gpr[3]) == ERESTARTSYS
                                                   >> 567                 || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
                                                   >> 568                 || ret == ERESTART_RESTARTBLOCK)) {
                                                   >> 569 
                                                   >> 570                 if (signr > 0
                                                   >> 571                     && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
                                                   >> 572                         || (ret == ERESTARTSYS
                                                   >> 573                             && !(ka->sa.sa_flags & SA_RESTART)))) {
                                                   >> 574                         /* make the system call return an EINTR error */
                                                   >> 575                         regs->result = -EINTR;
                                                   >> 576                         regs->gpr[3] = EINTR;
                                                   >> 577                         /* note that the cr0.SO bit is already set */
                                                   >> 578                 } else {
                                                   >> 579                         regs->nip -= 4; /* Back up & retry system call */
                                                   >> 580                         regs->result = 0;
                                                   >> 581                         regs->trap = 0;
                                                   >> 582                         if (ret == ERESTART_RESTARTBLOCK)
                                                   >> 583                                 regs->gpr[0] = __NR_restart_syscall;
                                                   >> 584                         else
                                                   >> 585                                 regs->gpr[3] = regs->orig_gpr3;
                                                   >> 586                 }
                                                   >> 587         }
                                                   >> 588 
                                                   >> 589         if (signr == 0)
                                                   >> 590                 return 0;               /* no signals delivered */
                                                   >> 591 
                                                   >> 592         if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
                                                   >> 593             && !on_sig_stack(regs->gpr[1]))
                                                   >> 594                 newsp = current->sas_ss_sp + current->sas_ss_size;
                                                   >> 595         else
                                                   >> 596                 newsp = regs->gpr[1];
                                                   >> 597         newsp &= ~0xfUL;
                                                   >> 598 
                                                   >> 599         /* Whee!  Actually deliver the signal.  */
                                                   >> 600         if (ka->sa.sa_flags & SA_SIGINFO)
                                                   >> 601                 handle_rt_signal(signr, ka, &info, oldset, regs, newsp);
                                                   >> 602         else
                                                   >> 603                 handle_signal(signr, ka, &info, oldset, regs, newsp);
                                                   >> 604 
                                                   >> 605         if (ka->sa.sa_flags & SA_ONESHOT)
                                                   >> 606                 ka->sa.sa_handler = SIG_DFL;
                                                   >> 607 
                                                   >> 608         if (!(ka->sa.sa_flags & SA_NODEFER)) {
                                                   >> 609                 spin_lock_irq(&current->sighand->siglock);
                                                   >> 610                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
                                                   >> 611                 sigaddset(&current->blocked, signr);
                                                   >> 612                 recalc_sigpending();
                                                   >> 613                 spin_unlock_irq(&current->sighand->siglock);
                                                   >> 614         }
                                                   >> 615 
                                                   >> 616         return 1;
                                                   >> 617 }
                                                   >> 618 
130                                                   619 

~ [ 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