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

TOMOYO Linux Cross Reference
Linux/arch/sh/kernel/signal_64.c

Version: ~ [ linux-6.0 ] ~ [ linux-5.19.12 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.71 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.146 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.215 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.260 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.295 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.330 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ 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  * arch/sh/kernel/signal_64.c
  3  *
  4  * Copyright (C) 2000, 2001  Paolo Alberelli
  5  * Copyright (C) 2003 - 2008  Paul Mundt
  6  * Copyright (C) 2004  Richard Curnow
  7  *
  8  * This file is subject to the terms and conditions of the GNU General Public
  9  * License.  See the file "COPYING" in the main directory of this archive
 10  * for more details.
 11  */
 12 #include <linux/rwsem.h>
 13 #include <linux/sched.h>
 14 #include <linux/mm.h>
 15 #include <linux/smp.h>
 16 #include <linux/kernel.h>
 17 #include <linux/signal.h>
 18 #include <linux/errno.h>
 19 #include <linux/wait.h>
 20 #include <linux/personality.h>
 21 #include <linux/ptrace.h>
 22 #include <linux/unistd.h>
 23 #include <linux/stddef.h>
 24 #include <linux/tracehook.h>
 25 #include <asm/ucontext.h>
 26 #include <asm/uaccess.h>
 27 #include <asm/pgtable.h>
 28 #include <asm/cacheflush.h>
 29 #include <asm/fpu.h>
 30 
 31 #define REG_RET 9
 32 #define REG_ARG1 2
 33 #define REG_ARG2 3
 34 #define REG_ARG3 4
 35 #define REG_SP 15
 36 #define REG_PR 18
 37 #define REF_REG_RET regs->regs[REG_RET]
 38 #define REF_REG_SP regs->regs[REG_SP]
 39 #define DEREF_REG_PR regs->regs[REG_PR]
 40 
 41 #define DEBUG_SIG 0
 42 
 43 static void
 44 handle_signal(struct ksignal *ksig, struct pt_regs *regs);
 45 
 46 static inline void
 47 handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
 48 {
 49         /* If we're not from a syscall, bail out */
 50         if (regs->syscall_nr < 0)
 51                 return;
 52 
 53         /* check for system call restart.. */
 54         switch (regs->regs[REG_RET]) {
 55                 case -ERESTART_RESTARTBLOCK:
 56                 case -ERESTARTNOHAND:
 57                 no_system_call_restart:
 58                         regs->regs[REG_RET] = -EINTR;
 59                         break;
 60 
 61                 case -ERESTARTSYS:
 62                         if (!(sa->sa_flags & SA_RESTART))
 63                                 goto no_system_call_restart;
 64                 /* fallthrough */
 65                 case -ERESTARTNOINTR:
 66                         /* Decode syscall # */
 67                         regs->regs[REG_RET] = regs->syscall_nr;
 68                         regs->pc -= 4;
 69                         break;
 70         }
 71 }
 72 
 73 /*
 74  * Note that 'init' is a special process: it doesn't get signals it doesn't
 75  * want to handle. Thus you cannot kill init even with a SIGKILL even by
 76  * mistake.
 77  *
 78  * Note that we go through the signals twice: once to check the signals that
 79  * the kernel can handle, and then we build all the user-level signal handling
 80  * stack-frames in one go after that.
 81  */
 82 static void do_signal(struct pt_regs *regs)
 83 {
 84         struct ksignal ksig;
 85 
 86         /*
 87          * We want the common case to go fast, which
 88          * is why we may in certain cases get here from
 89          * kernel mode. Just return without doing anything
 90          * if so.
 91          */
 92         if (!user_mode(regs))
 93                 return;
 94 
 95         if (get_signal(&ksig)) {
 96                 handle_syscall_restart(regs, &ksig.ka.sa);
 97 
 98                 /* Whee!  Actually deliver the signal.  */
 99                 handle_signal(&ksig, regs);
100                 return;
101         }
102 
103         /* Did we come from a system call? */
104         if (regs->syscall_nr >= 0) {
105                 /* Restart the system call - no handlers present */
106                 switch (regs->regs[REG_RET]) {
107                 case -ERESTARTNOHAND:
108                 case -ERESTARTSYS:
109                 case -ERESTARTNOINTR:
110                         /* Decode Syscall # */
111                         regs->regs[REG_RET] = regs->syscall_nr;
112                         regs->pc -= 4;
113                         break;
114 
115                 case -ERESTART_RESTARTBLOCK:
116                         regs->regs[REG_RET] = __NR_restart_syscall;
117                         regs->pc -= 4;
118                         break;
119                 }
120         }
121 
122         /* No signal to deliver -- put the saved sigmask back */
123         restore_saved_sigmask();
124 }
125 
126 /*
127  * Do a signal return; undo the signal stack.
128  */
129 struct sigframe {
130         struct sigcontext sc;
131         unsigned long extramask[_NSIG_WORDS-1];
132         long long retcode[2];
133 };
134 
135 struct rt_sigframe {
136         struct siginfo __user *pinfo;
137         void *puc;
138         struct siginfo info;
139         struct ucontext uc;
140         long long retcode[2];
141 };
142 
143 #ifdef CONFIG_SH_FPU
144 static inline int
145 restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
146 {
147         int err = 0;
148         int fpvalid;
149 
150         err |= __get_user (fpvalid, &sc->sc_fpvalid);
151         conditional_used_math(fpvalid);
152         if (! fpvalid)
153                 return err;
154 
155         if (current == last_task_used_math) {
156                 last_task_used_math = NULL;
157                 regs->sr |= SR_FD;
158         }
159 
160         err |= __copy_from_user(&current->thread.xstate->hardfpu, &sc->sc_fpregs[0],
161                                 (sizeof(long long) * 32) + (sizeof(int) * 1));
162 
163         return err;
164 }
165 
166 static inline int
167 setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
168 {
169         int err = 0;
170         int fpvalid;
171 
172         fpvalid = !!used_math();
173         err |= __put_user(fpvalid, &sc->sc_fpvalid);
174         if (! fpvalid)
175                 return err;
176 
177         if (current == last_task_used_math) {
178                 enable_fpu();
179                 save_fpu(current);
180                 disable_fpu();
181                 last_task_used_math = NULL;
182                 regs->sr |= SR_FD;
183         }
184 
185         err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.xstate->hardfpu,
186                               (sizeof(long long) * 32) + (sizeof(int) * 1));
187         clear_used_math();
188 
189         return err;
190 }
191 #else
192 static inline int
193 restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
194 {
195         return 0;
196 }
197 static inline int
198 setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
199 {
200         return 0;
201 }
202 #endif
203 
204 static int
205 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, long long *r2_p)
206 {
207         unsigned int err = 0;
208         unsigned long long current_sr, new_sr;
209 #define SR_MASK 0xffff8cfd
210 
211 #define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
212 
213         COPY(regs[0]);  COPY(regs[1]);  COPY(regs[2]);  COPY(regs[3]);
214         COPY(regs[4]);  COPY(regs[5]);  COPY(regs[6]);  COPY(regs[7]);
215         COPY(regs[8]);  COPY(regs[9]);  COPY(regs[10]); COPY(regs[11]);
216         COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
217         COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
218         COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
219         COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
220         COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
221         COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
222         COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
223         COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
224         COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
225         COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
226         COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
227         COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
228         COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
229         COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
230         COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
231 
232         /* Prevent the signal handler manipulating SR in a way that can
233            crash the kernel. i.e. only allow S, Q, M, PR, SZ, FR to be
234            modified */
235         current_sr = regs->sr;
236         err |= __get_user(new_sr, &sc->sc_sr);
237         regs->sr &= SR_MASK;
238         regs->sr |= (new_sr & ~SR_MASK);
239 
240         COPY(pc);
241 
242 #undef COPY
243 
244         /* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr
245          * has been restored above.) */
246         err |= restore_sigcontext_fpu(regs, sc);
247 
248         regs->syscall_nr = -1;          /* disable syscall checks */
249         err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]);
250         return err;
251 }
252 
253 asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
254                                    unsigned long r4, unsigned long r5,
255                                    unsigned long r6, unsigned long r7,
256                                    struct pt_regs * regs)
257 {
258         struct sigframe __user *frame = (struct sigframe __user *) (long) REF_REG_SP;
259         sigset_t set;
260         long long ret;
261 
262         /* Always make any pending restarted system calls return -EINTR */
263         current->restart_block.fn = do_no_restart_syscall;
264 
265         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
266                 goto badframe;
267 
268         if (__get_user(set.sig[0], &frame->sc.oldmask)
269             || (_NSIG_WORDS > 1
270                 && __copy_from_user(&set.sig[1], &frame->extramask,
271                                     sizeof(frame->extramask))))
272                 goto badframe;
273 
274         set_current_blocked(&set);
275 
276         if (restore_sigcontext(regs, &frame->sc, &ret))
277                 goto badframe;
278         regs->pc -= 4;
279 
280         return (int) ret;
281 
282 badframe:
283         force_sig(SIGSEGV, current);
284         return 0;
285 }
286 
287 asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
288                                 unsigned long r4, unsigned long r5,
289                                 unsigned long r6, unsigned long r7,
290                                 struct pt_regs * regs)
291 {
292         struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP;
293         sigset_t set;
294         long long ret;
295 
296         /* Always make any pending restarted system calls return -EINTR */
297         current->restart_block.fn = do_no_restart_syscall;
298 
299         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
300                 goto badframe;
301 
302         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
303                 goto badframe;
304 
305         set_current_blocked(&set);
306 
307         if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
308                 goto badframe;
309         regs->pc -= 4;
310 
311         if (restore_altstack(&frame->uc.uc_stack))
312                 goto badframe;
313 
314         return (int) ret;
315 
316 badframe:
317         force_sig(SIGSEGV, current);
318         return 0;
319 }
320 
321 /*
322  * Set up a signal frame.
323  */
324 static int
325 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
326                  unsigned long mask)
327 {
328         int err = 0;
329 
330         /* Do this first, otherwise is this sets sr->fd, that value isn't preserved. */
331         err |= setup_sigcontext_fpu(regs, sc);
332 
333 #define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
334 
335         COPY(regs[0]);  COPY(regs[1]);  COPY(regs[2]);  COPY(regs[3]);
336         COPY(regs[4]);  COPY(regs[5]);  COPY(regs[6]);  COPY(regs[7]);
337         COPY(regs[8]);  COPY(regs[9]);  COPY(regs[10]); COPY(regs[11]);
338         COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
339         COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
340         COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
341         COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
342         COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
343         COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
344         COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
345         COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
346         COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
347         COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
348         COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
349         COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
350         COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
351         COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
352         COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
353         COPY(sr);       COPY(pc);
354 
355 #undef COPY
356 
357         err |= __put_user(mask, &sc->oldmask);
358 
359         return err;
360 }
361 
362 /*
363  * Determine which stack to use..
364  */
365 static inline void __user *
366 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
367 {
368         if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
369                 sp = current->sas_ss_sp + current->sas_ss_size;
370 
371         return (void __user *)((sp - frame_size) & -8ul);
372 }
373 
374 void sa_default_restorer(void);         /* See comments below */
375 void sa_default_rt_restorer(void);      /* See comments below */
376 
377 static int setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
378 {
379         struct sigframe __user *frame;
380         int err = 0, sig = ksig->sig;
381         int signal;
382 
383         frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
384 
385         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
386                 return -EFAULT;
387 
388         err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
389 
390         /* Give up earlier as i386, in case */
391         if (err)
392                 return -EFAULT;
393 
394         if (_NSIG_WORDS > 1) {
395                 err |= __copy_to_user(frame->extramask, &set->sig[1],
396                                       sizeof(frame->extramask)); }
397 
398         /* Give up earlier as i386, in case */
399         if (err)
400                 return -EFAULT;
401 
402         /* Set up to return from userspace.  If provided, use a stub
403            already in userspace.  */
404         if (ksig->ka.sa.sa_flags & SA_RESTORER) {
405                 /*
406                  * On SH5 all edited pointers are subject to NEFF
407                  */
408                 DEREF_REG_PR = neff_sign_extend((unsigned long)
409                         ksig->ka->sa.sa_restorer | 0x1);
410         } else {
411                 /*
412                  * Different approach on SH5.
413                  * . Endianness independent asm code gets placed in entry.S .
414                  *   This is limited to four ASM instructions corresponding
415                  *   to two long longs in size.
416                  * . err checking is done on the else branch only
417                  * . flush_icache_range() is called upon __put_user() only
418                  * . all edited pointers are subject to NEFF
419                  * . being code, linker turns ShMedia bit on, always
420                  *   dereference index -1.
421                  */
422                 DEREF_REG_PR = neff_sign_extend((unsigned long)
423                         frame->retcode | 0x01);
424 
425                 if (__copy_to_user(frame->retcode,
426                         (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
427                         return -EFAULT;
428 
429                 /* Cohere the trampoline with the I-cache. */
430                 flush_cache_sigtramp(DEREF_REG_PR-1);
431         }
432 
433         /*
434          * Set up registers for signal handler.
435          * All edited pointers are subject to NEFF.
436          */
437         regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
438         regs->regs[REG_ARG1] = sig; /* Arg for signal handler */
439 
440         /* FIXME:
441            The glibc profiling support for SH-5 needs to be passed a sigcontext
442            so it can retrieve the PC.  At some point during 2003 the glibc
443            support was changed to receive the sigcontext through the 2nd
444            argument, but there are still versions of libc.so in use that use
445            the 3rd argument.  Until libc.so is stabilised, pass the sigcontext
446            through both 2nd and 3rd arguments.
447         */
448 
449         regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
450         regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
451 
452         regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
453 
454         /* Broken %016Lx */
455         pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
456                  sig, current->comm, current->pid, frame,
457                  regs->pc >> 32, regs->pc & 0xffffffff,
458                  DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
459 
460         return 0;
461 }
462 
463 static int setup_rt_frame(struct ksignal *kig, sigset_t *set,
464                           struct pt_regs *regs)
465 {
466         struct rt_sigframe __user *frame;
467         int err = 0, sig = ksig->sig;
468 
469         frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
470 
471         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
472                 return -EFAULT;
473 
474         err |= __put_user(&frame->info, &frame->pinfo);
475         err |= __put_user(&frame->uc, &frame->puc);
476         err |= copy_siginfo_to_user(&frame->info, &ksig->info);
477 
478         /* Give up earlier as i386, in case */
479         if (err)
480                 return -EFAULT;
481 
482         /* Create the ucontext.  */
483         err |= __put_user(0, &frame->uc.uc_flags);
484         err |= __put_user(0, &frame->uc.uc_link);
485         err |= __save_altstack(&frame->uc.uc_stack, regs->regs[REG_SP]);
486         err |= setup_sigcontext(&frame->uc.uc_mcontext,
487                                 regs, set->sig[0]);
488         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
489 
490         /* Give up earlier as i386, in case */
491         if (err)
492                 return -EFAULT;
493 
494         /* Set up to return from userspace.  If provided, use a stub
495            already in userspace.  */
496         if (ksig->ka.sa.sa_flags & SA_RESTORER) {
497                 /*
498                  * On SH5 all edited pointers are subject to NEFF
499                  */
500                 DEREF_REG_PR = neff_sign_extend((unsigned long)
501                         ksig->ka.sa.sa_restorer | 0x1);
502         } else {
503                 /*
504                  * Different approach on SH5.
505                  * . Endianness independent asm code gets placed in entry.S .
506                  *   This is limited to four ASM instructions corresponding
507                  *   to two long longs in size.
508                  * . err checking is done on the else branch only
509                  * . flush_icache_range() is called upon __put_user() only
510                  * . all edited pointers are subject to NEFF
511                  * . being code, linker turns ShMedia bit on, always
512                  *   dereference index -1.
513                  */
514                 DEREF_REG_PR = neff_sign_extend((unsigned long)
515                         frame->retcode | 0x01);
516 
517                 if (__copy_to_user(frame->retcode,
518                         (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
519                         return -EFAULT;
520 
521                 /* Cohere the trampoline with the I-cache. */
522                 flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
523         }
524 
525         /*
526          * Set up registers for signal handler.
527          * All edited pointers are subject to NEFF.
528          */
529         regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
530         regs->regs[REG_ARG1] = sig; /* Arg for signal handler */
531         regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
532         regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
533         regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
534 
535         pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
536                  sig, current->comm, current->pid, frame,
537                  regs->pc >> 32, regs->pc & 0xffffffff,
538                  DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
539 
540         return 0;
541 }
542 
543 /*
544  * OK, we're invoking a handler
545  */
546 static void
547 handle_signal(struct ksignal *ksig, struct pt_regs *regs)
548 {
549         sigset_t *oldset = sigmask_to_save();
550         int ret;
551 
552         /* Set up the stack frame */
553         if (ksig->ka.sa.sa_flags & SA_SIGINFO)
554                 ret = setup_rt_frame(ksig, oldset, regs);
555         else
556                 ret = setup_frame(ksig, oldset, regs);
557 
558         signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
559 }
560 
561 asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
562 {
563         if (thread_info_flags & _TIF_SIGPENDING)
564                 do_signal(regs);
565 
566         if (thread_info_flags & _TIF_NOTIFY_RESUME) {
567                 clear_thread_flag(TIF_NOTIFY_RESUME);
568                 tracehook_notify_resume(regs);
569         }
570 }
571 

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