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

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

Version: ~ [ linux-6.4-rc3 ] ~ [ linux-6.3.4 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.30 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.113 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.180 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.243 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.283 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.315 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * This file is subject to the terms and conditions of the GNU General Public
  3  * License.  See the file "COPYING" in the main directory of this archive
  4  * for more details.
  5  *
  6  * Copyright (C) 1991, 1992  Linus Torvalds
  7  * Copyright (C) 1994 - 2000  Ralf Baechle
  8  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  9  */
 10 #include <linux/config.h>
 11 #include <linux/sched.h>
 12 #include <linux/mm.h>
 13 #include <linux/smp.h>
 14 #include <linux/smp_lock.h>
 15 #include <linux/kernel.h>
 16 #include <linux/signal.h>
 17 #include <linux/errno.h>
 18 #include <linux/wait.h>
 19 #include <linux/ptrace.h>
 20 #include <linux/unistd.h>
 21 
 22 #include <asm/asm.h>
 23 #include <asm/bitops.h>
 24 #include <asm/pgalloc.h>
 25 #include <asm/stackframe.h>
 26 #include <asm/uaccess.h>
 27 #include <asm/ucontext.h>
 28 #include <asm/system.h>
 29 #include <asm/fpu.h>
 30 
 31 #define DEBUG_SIG 0
 32 
 33 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 34 
 35 extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
 36 
 37 extern asmlinkage void syscall_trace(void);
 38 
 39 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
 40 {
 41         if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
 42                 return -EFAULT;
 43         if (from->si_code < 0)
 44                 return __copy_to_user(to, from, sizeof(siginfo_t));
 45         else {
 46                 int err;
 47 
 48                 /* If you change siginfo_t structure, please be sure
 49                    this code is fixed accordingly.
 50                    It should never copy any pad contained in the structure
 51                    to avoid security leaks, but must copy the generic
 52                    3 ints plus the relevant union member.  */
 53                 err = __put_user(from->si_signo, &to->si_signo);
 54                 err |= __put_user(from->si_errno, &to->si_errno);
 55                 err |= __put_user((short)from->si_code, &to->si_code);
 56                 switch (from->si_code >> 16) {
 57                 case __SI_FAULT >> 16:
 58                         err |= __put_user((long)from->si_addr, &to->si_addr);
 59                         break;
 60                 case __SI_CHLD >> 16:
 61                         err |= __put_user(from->si_utime, &to->si_utime);
 62                         err |= __put_user(from->si_stime, &to->si_stime);
 63                         err |= __put_user(from->si_status, &to->si_status);
 64                 default:
 65                         err |= __put_user(from->si_pid, &to->si_pid);
 66                         err |= __put_user(from->si_uid, &to->si_uid);
 67                         break;
 68                 /* case __SI_RT: This is not generated by the kernel as of now.  */
 69                 }
 70                 return err;
 71         }
 72 }
 73 
 74 /*
 75  * Atomically swap in the new signal mask, and wait for a signal.
 76  */
 77 save_static_function(sys_rt_sigsuspend);
 78 static_unused int _sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs)
 79 {
 80         sigset_t *unewset, saveset, newset;
 81         size_t sigsetsize;
 82 
 83         /* XXX Don't preclude handling different sized sigset_t's.  */
 84         sigsetsize = regs.regs[5];
 85         if (sigsetsize != sizeof(sigset_t))
 86                 return -EINVAL;
 87 
 88         unewset = (sigset_t *) regs.regs[4];
 89         if (copy_from_user(&newset, unewset, sizeof(newset)))
 90                 return -EFAULT;
 91         sigdelsetmask(&newset, ~_BLOCKABLE);
 92 
 93         spin_lock_irq(&current->sigmask_lock);
 94         saveset = current->blocked;
 95         current->blocked = newset;
 96         recalc_sigpending(current);
 97         spin_unlock_irq(&current->sigmask_lock);
 98 
 99         regs.regs[2] = EINTR;
100         regs.regs[7] = 1;
101         while (1) {
102                 current->state = TASK_INTERRUPTIBLE;
103                 schedule();
104                 if (do_signal(&saveset, &regs))
105                         return -EINTR;
106         }
107 }
108 
109 asmlinkage int sys_sigaltstack(abi64_no_regargs, struct pt_regs regs)
110 {
111         const stack_t *uss = (const stack_t *) regs.regs[4];
112         stack_t *uoss = (stack_t *) regs.regs[5];
113         unsigned long usp = regs.regs[29];
114 
115         return do_sigaltstack(uss, uoss, usp);
116 }
117 
118 asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
119 {
120         int err = 0;
121 
122         err |= __get_user(regs->cp0_epc, &sc->sc_pc);
123         err |= __get_user(regs->hi, &sc->sc_mdhi);
124         err |= __get_user(regs->lo, &sc->sc_mdlo);
125 
126 #define restore_gp_reg(i) do {                                          \
127         err |= __get_user(regs->regs[i], &sc->sc_regs[i]);              \
128 } while(0)
129         restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
130         restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
131         restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
132         restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
133         restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
134         restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
135         restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
136         restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
137         restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
138         restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
139         restore_gp_reg(31);
140 #undef restore_gp_reg
141 
142         err |= __get_user(current->used_math, &sc->sc_used_math);
143 
144         if (current->used_math) {
145                 /* restore fpu context if we have used it before */
146                 own_fpu();
147                 err |= restore_fp_context(sc);
148         } else {
149                 /* signal handler may have used FPU.  Give it up. */
150                 lose_fpu();
151         }
152 
153         return err;
154 }
155 
156 struct rt_sigframe {
157         u32 rs_ass[4];                  /* argument save space for o32 */
158         u32 rs_code[2];                 /* signal trampoline */
159         struct siginfo rs_info;
160         struct ucontext rs_uc;
161 };
162 
163 asmlinkage void sys_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
164 {
165         struct rt_sigframe *frame;
166         sigset_t set;
167         stack_t st;
168 
169         frame = (struct rt_sigframe *) regs.regs[29];
170         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
171                 goto badframe;
172         if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
173                 goto badframe;
174 
175         sigdelsetmask(&set, ~_BLOCKABLE);
176         spin_lock_irq(&current->sigmask_lock);
177         current->blocked = set;
178         recalc_sigpending(current);
179         spin_unlock_irq(&current->sigmask_lock);
180 
181         if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
182                 goto badframe;
183 
184         if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
185                 goto badframe;
186         /* It is more difficult to avoid calling this function than to
187            call it and ignore errors.  */
188         do_sigaltstack(&st, NULL, regs.regs[29]);
189 
190         /*
191          * Don't let your children do this ...
192          */
193         __asm__ __volatile__(
194                 "move\t$29, %0\n\t"
195                 "j\tret_from_sys_call"
196                 :/* no outputs */
197                 :"r" (&regs));
198         /* Unreached */
199 
200 badframe:
201         force_sig(SIGSEGV, current);
202 }
203 
204 int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
205 {
206         int err = 0;
207 
208         err |= __put_user(regs->cp0_epc, &sc->sc_pc);
209         err |= __put_user(regs->cp0_status, &sc->sc_status);
210 
211 #define save_gp_reg(i) do {                                             \
212         err |= __put_user(regs->regs[i], &sc->sc_regs[i]);              \
213 } while(0)
214         __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
215         save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
216         save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
217         save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
218         save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
219         save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
220         save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
221         save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
222         save_gp_reg(31);
223 #undef save_gp_reg
224 
225         err |= __put_user(regs->hi, &sc->sc_mdhi);
226         err |= __put_user(regs->lo, &sc->sc_mdlo);
227         err |= __put_user(regs->cp0_cause, &sc->sc_cause);
228         err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
229 
230         err |= __put_user(current->used_math, &sc->sc_used_math);
231 
232         if (!current->used_math)
233                 goto out;
234 
235         /* 
236          * Save FPU state to signal context.  Signal handler will "inherit"
237          * current FPU state.
238          */
239         if (!is_fpu_owner()) {
240                 own_fpu();
241                 restore_fp(current);
242         }
243         err |= save_fp_context(sc);
244 
245 out:
246         return err;
247 }
248 
249 /*
250  * Determine which stack to use..
251  */
252 static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
253         size_t frame_size)
254 {
255         unsigned long sp;
256 
257         /* Default to using normal stack */
258         sp = regs->regs[29];
259 
260         /*
261          * FPU emulator may have it's own trampoline active just
262          * above the user stack, 16-bytes before the next lowest
263          * 16 byte boundary.  Try to avoid trashing it.
264          */
265         sp -= 32;
266 
267         /* This is the X/Open sanctioned signal stack switching.  */
268         if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
269                 sp = current->sas_ss_sp + current->sas_ss_size;
270 
271         return (void *)((sp - frame_size) & ALMASK);
272 }
273 
274 static void inline setup_rt_frame(struct k_sigaction * ka,
275         struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
276 {
277         struct rt_sigframe *frame;
278         int err = 0;
279 
280         frame = get_sigframe(ka, regs, sizeof(*frame));
281         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
282                 goto give_sigsegv;
283 
284         /*
285          * Set up the return code ...
286          *
287          *         li      v0, __NR_rt_sigreturn
288          *         syscall
289          */
290         err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
291         err |= __put_user(0x0000000c                    , frame->rs_code + 1);
292         flush_cache_sigtramp((unsigned long) frame->rs_code);
293 
294         /* Create siginfo.  */
295         err |= copy_siginfo_to_user(&frame->rs_info, info);
296 
297         /* Create the ucontext.  */
298         err |= __put_user(0, &frame->rs_uc.uc_flags);
299         err |= __put_user(0, &frame->rs_uc.uc_link);
300         err |= __put_user((void *)current->sas_ss_sp,
301                           &frame->rs_uc.uc_stack.ss_sp);
302         err |= __put_user(sas_ss_flags(regs->regs[29]),
303                           &frame->rs_uc.uc_stack.ss_flags);
304         err |= __put_user(current->sas_ss_size,
305                           &frame->rs_uc.uc_stack.ss_size);
306         err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
307         err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
308 
309         if (err)
310                 goto give_sigsegv;
311 
312         /*
313          * Arguments to signal handler:
314          *
315          *   a0 = signal number
316          *   a1 = 0 (should be cause)
317          *   a2 = pointer to ucontext
318          *
319          * $25 and c0_epc point to the signal handler, $29 points to
320          * the struct rt_sigframe.
321          */
322         regs->regs[ 4] = signr;
323         regs->regs[ 5] = (unsigned long) &frame->rs_info;
324         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
325         regs->regs[29] = (unsigned long) frame;
326         regs->regs[31] = (unsigned long) frame->rs_code;
327         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
328 
329 #if DEBUG_SIG
330         printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
331                current->comm, current->pid,
332                frame, regs->cp0_epc, regs->regs[31]);
333 #endif
334         return;
335 
336 give_sigsegv:
337         if (signr == SIGSEGV)
338                 ka->sa.sa_handler = SIG_DFL;
339         force_sig(SIGSEGV, current);
340 }
341 
342 extern void setup_rt_frame_n32(struct k_sigaction * ka,
343         struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info);
344 
345 static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
346         siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
347 {
348 #ifdef CONFIG_MIPS32_N32
349         if ((current->thread.mflags & MF_ABI_MASK) == MF_N32)
350                 setup_rt_frame_n32 (ka, regs, sig, oldset, info);
351         else
352 #endif
353                 setup_rt_frame(ka, regs, sig, oldset, info);
354 
355         if (ka->sa.sa_flags & SA_ONESHOT)
356                 ka->sa.sa_handler = SIG_DFL;
357         if (!(ka->sa.sa_flags & SA_NODEFER)) {
358                 spin_lock_irq(&current->sigmask_lock);
359                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
360                 sigaddset(&current->blocked,sig);
361                 recalc_sigpending(current);
362                 spin_unlock_irq(&current->sigmask_lock);
363         }
364 }
365 
366 static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
367 {
368         switch(regs->regs[0]) {
369         case ERESTARTNOHAND:
370                 regs->regs[2] = EINTR;
371                 break;
372         case ERESTARTSYS:
373                 if(!(ka->sa.sa_flags & SA_RESTART)) {
374                         regs->regs[2] = EINTR;
375                         break;
376                 }
377         /* fallthrough */
378         case ERESTARTNOINTR:            /* Userland will reload $v0.  */
379                 regs->regs[7] = regs->regs[26];
380                 regs->cp0_epc -= 8;
381         }
382 
383         regs->regs[0] = 0;              /* Don't deal with this again.  */
384 }
385 
386 extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
387 extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
388 
389 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
390 {
391         struct k_sigaction *ka;
392         siginfo_t info;
393 
394 #ifdef CONFIG_BINFMT_ELF32
395         if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) {
396                 return do_signal32(oldset, regs);
397         }
398 #endif
399 
400         if (!oldset)
401                 oldset = &current->blocked;
402 
403         for (;;) {
404                 unsigned long signr;
405 
406                 spin_lock_irq(&current->sigmask_lock);
407                 signr = dequeue_signal(&current->blocked, &info);
408                 spin_unlock_irq(&current->sigmask_lock);
409 
410                 if (!signr)
411                         break;
412 
413                 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
414                         /* Let the debugger run.  */
415                         current->exit_code = signr;
416                         current->state = TASK_STOPPED;
417                         notify_parent(current, SIGCHLD);
418                         schedule();
419 
420                         /* We're back.  Did the debugger cancel the sig?  */
421                         if (!(signr = current->exit_code))
422                                 continue;
423                         current->exit_code = 0;
424 
425                         /* The debugger continued.  Ignore SIGSTOP.  */
426                         if (signr == SIGSTOP)
427                                 continue;
428 
429                         /* Update the siginfo structure.  Is this good?  */
430                         if (signr != info.si_signo) {
431                                 info.si_signo = signr;
432                                 info.si_errno = 0;
433                                 info.si_code = SI_USER;
434                                 info.si_pid = current->p_pptr->pid;
435                                 info.si_uid = current->p_pptr->uid;
436                         }
437 
438                         /* If the (new) signal is now blocked, requeue it.  */
439                         if (sigismember(&current->blocked, signr)) {
440                                 send_sig_info(signr, &info, current);
441                                 continue;
442                         }
443                 }
444 
445                 ka = &current->sig->action[signr-1];
446                 if (ka->sa.sa_handler == SIG_IGN) {
447                         if (signr != SIGCHLD)
448                                 continue;
449                         /* Check for SIGCHLD: it's special.  */
450                         while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
451                                 /* nothing */;
452                         continue;
453                 }
454 
455                 if (ka->sa.sa_handler == SIG_DFL) {
456                         int exit_code = signr;
457 
458                         /* Init gets no signals it doesn't want.  */
459                         if (current->pid == 1)
460                                 continue;
461 
462                         switch (signr) {
463                         case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
464                                 continue;
465 
466                         case SIGTSTP: case SIGTTIN: case SIGTTOU:
467                                 if (is_orphaned_pgrp(current->pgrp))
468                                         continue;
469                                 /* FALLTHRU */
470 
471                         case SIGSTOP:
472                                 current->state = TASK_STOPPED;
473                                 current->exit_code = signr;
474                                 if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
475                                         notify_parent(current, SIGCHLD);
476                                 schedule();
477                                 continue;
478 
479                         case SIGQUIT: case SIGILL: case SIGTRAP:
480                         case SIGABRT: case SIGFPE: case SIGSEGV:
481                         case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
482                                 if (do_coredump(signr, regs))
483                                         exit_code |= 0x80;
484                                 /* FALLTHRU */
485 
486                         default:
487                                 sig_exit(signr, exit_code, &info);
488                                 /* NOTREACHED */
489                         }
490                 }
491 
492                 if (regs->regs[0])
493                         syscall_restart(regs, ka);
494                 /* Whee!  Actually deliver the signal.  */
495                 handle_signal(signr, ka, &info, oldset, regs);
496                 return 1;
497         }
498 
499         /*
500          * Who's code doesn't conform to the restartable syscall convention
501          * dies here!!!  The li instruction, a single machine instruction,
502          * must directly be followed by the syscall instruction.
503          */
504         if (regs->regs[0]) {
505                 if (regs->regs[2] == ERESTARTNOHAND ||
506                     regs->regs[2] == ERESTARTSYS ||
507                     regs->regs[2] == ERESTARTNOINTR) {
508                         regs->regs[7] = regs->regs[26];
509                         regs->cp0_epc -= 8;
510                 }
511         }
512         return 0;
513 }
514 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp