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

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

Version: ~ [ linux-6.0-rc6 ] ~ [ linux-5.19.10 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.69 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.144 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.214 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.259 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.294 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.329 ] ~ [ 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  *    Copyright IBM Corp. 1999, 2006
  3  *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
  4  *
  5  *    Based on Intel version
  6  * 
  7  *  Copyright (C) 1991, 1992  Linus Torvalds
  8  *
  9  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
 10  */
 11 
 12 #include <linux/sched.h>
 13 #include <linux/mm.h>
 14 #include <linux/smp.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 #include <linux/stddef.h>
 22 #include <linux/tty.h>
 23 #include <linux/personality.h>
 24 #include <linux/binfmts.h>
 25 #include <linux/tracehook.h>
 26 #include <linux/syscalls.h>
 27 #include <linux/compat.h>
 28 #include <asm/ucontext.h>
 29 #include <asm/uaccess.h>
 30 #include <asm/lowcore.h>
 31 #include <asm/switch_to.h>
 32 #include "entry.h"
 33 
 34 /*
 35  * Layout of an old-style signal-frame:
 36  *      -----------------------------------------
 37  *      | save area (_SIGNAL_FRAMESIZE)         |
 38  *      -----------------------------------------
 39  *      | struct sigcontext                     |
 40  *      |       oldmask                         |
 41  *      |       _sigregs *                      |
 42  *      -----------------------------------------
 43  *      | _sigregs with                         |
 44  *      |       _s390_regs_common               |
 45  *      |       _s390_fp_regs                   |
 46  *      -----------------------------------------
 47  *      | int signo                             |
 48  *      -----------------------------------------
 49  *      | _sigregs_ext with                     |
 50  *      |       gprs_high 64 byte (opt)         |
 51  *      |       vxrs_low 128 byte (opt)         |
 52  *      |       vxrs_high 256 byte (opt)        |
 53  *      |       reserved 128 byte (opt)         |
 54  *      -----------------------------------------
 55  *      | __u16 svc_insn                        |
 56  *      -----------------------------------------
 57  * The svc_insn entry with the sigreturn system call opcode does not
 58  * have a fixed position and moves if gprs_high or vxrs exist.
 59  * Future extensions will be added to _sigregs_ext.
 60  */
 61 struct sigframe
 62 {
 63         __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
 64         struct sigcontext sc;
 65         _sigregs sregs;
 66         int signo;
 67         _sigregs_ext sregs_ext;
 68         __u16 svc_insn;         /* Offset of svc_insn is NOT fixed! */
 69 };
 70 
 71 /*
 72  * Layout of an rt signal-frame:
 73  *      -----------------------------------------
 74  *      | save area (_SIGNAL_FRAMESIZE)         |
 75  *      -----------------------------------------
 76  *      | svc __NR_rt_sigreturn 2 byte          |
 77  *      -----------------------------------------
 78  *      | struct siginfo                        |
 79  *      -----------------------------------------
 80  *      | struct ucontext_extended with         |
 81  *      |       unsigned long uc_flags          |
 82  *      |       struct ucontext *uc_link        |
 83  *      |       stack_t uc_stack                |
 84  *      |       _sigregs uc_mcontext with       |
 85  *      |               _s390_regs_common       |
 86  *      |               _s390_fp_regs           |
 87  *      |       sigset_t uc_sigmask             |
 88  *      |       _sigregs_ext uc_mcontext_ext    |
 89  *      |               gprs_high 64 byte (opt) |
 90  *      |               vxrs_low 128 byte (opt) |
 91  *      |               vxrs_high 256 byte (opt)|
 92  *      |               reserved 128 byte (opt) |
 93  *      -----------------------------------------
 94  * Future extensions will be added to _sigregs_ext.
 95  */
 96 struct rt_sigframe
 97 {
 98         __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
 99         __u16 svc_insn;
100         struct siginfo info;
101         struct ucontext_extended uc;
102 };
103 
104 /* Store registers needed to create the signal frame */
105 static void store_sigregs(void)
106 {
107         save_access_regs(current->thread.acrs);
108         save_fp_ctl(&current->thread.fp_regs.fpc);
109 #ifdef CONFIG_64BIT
110         if (current->thread.vxrs) {
111                 int i;
112 
113                 save_vx_regs(current->thread.vxrs);
114                 for (i = 0; i < __NUM_FPRS; i++)
115                         current->thread.fp_regs.fprs[i] =
116                                 *(freg_t *)(current->thread.vxrs + i);
117         } else
118 #endif
119                 save_fp_regs(current->thread.fp_regs.fprs);
120 }
121 
122 /* Load registers after signal return */
123 static void load_sigregs(void)
124 {
125         restore_access_regs(current->thread.acrs);
126         /* restore_fp_ctl is done in restore_sigregs */
127 #ifdef CONFIG_64BIT
128         if (current->thread.vxrs) {
129                 int i;
130 
131                 for (i = 0; i < __NUM_FPRS; i++)
132                         *(freg_t *)(current->thread.vxrs + i) =
133                                 current->thread.fp_regs.fprs[i];
134                 restore_vx_regs(current->thread.vxrs);
135         } else
136 #endif
137                 restore_fp_regs(current->thread.fp_regs.fprs);
138 }
139 
140 /* Returns non-zero on fault. */
141 static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
142 {
143         _sigregs user_sregs;
144 
145         /* Copy a 'clean' PSW mask to the user to avoid leaking
146            information about whether PER is currently on.  */
147         user_sregs.regs.psw.mask = PSW_USER_BITS |
148                 (regs->psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
149         user_sregs.regs.psw.addr = regs->psw.addr;
150         memcpy(&user_sregs.regs.gprs, &regs->gprs, sizeof(sregs->regs.gprs));
151         memcpy(&user_sregs.regs.acrs, current->thread.acrs,
152                sizeof(user_sregs.regs.acrs));
153         memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
154                sizeof(user_sregs.fpregs));
155         if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs)))
156                 return -EFAULT;
157         return 0;
158 }
159 
160 static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
161 {
162         _sigregs user_sregs;
163 
164         /* Alwys make any pending restarted system call return -EINTR */
165         current->restart_block.fn = do_no_restart_syscall;
166 
167         if (__copy_from_user(&user_sregs, sregs, sizeof(user_sregs)))
168                 return -EFAULT;
169 
170         if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW_MASK_RI))
171                 return -EINVAL;
172 
173         /* Loading the floating-point-control word can fail. Do that first. */
174         if (restore_fp_ctl(&user_sregs.fpregs.fpc))
175                 return -EINVAL;
176 
177         /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
178         regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
179                 (user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
180         /* Check for invalid user address space control. */
181         if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
182                 regs->psw.mask = PSW_ASC_PRIMARY |
183                         (regs->psw.mask & ~PSW_MASK_ASC);
184         /* Check for invalid amode */
185         if (regs->psw.mask & PSW_MASK_EA)
186                 regs->psw.mask |= PSW_MASK_BA;
187         regs->psw.addr = user_sregs.regs.psw.addr;
188         memcpy(&regs->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs));
189         memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
190                sizeof(current->thread.acrs));
191 
192         memcpy(&current->thread.fp_regs, &user_sregs.fpregs,
193                sizeof(current->thread.fp_regs));
194 
195         clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */
196         return 0;
197 }
198 
199 /* Returns non-zero on fault. */
200 static int save_sigregs_ext(struct pt_regs *regs,
201                             _sigregs_ext __user *sregs_ext)
202 {
203 #ifdef CONFIG_64BIT
204         __u64 vxrs[__NUM_VXRS_LOW];
205         int i;
206 
207         /* Save vector registers to signal stack */
208         if (current->thread.vxrs) {
209                 for (i = 0; i < __NUM_VXRS_LOW; i++)
210                         vxrs[i] = *((__u64 *)(current->thread.vxrs + i) + 1);
211                 if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
212                                    sizeof(sregs_ext->vxrs_low)) ||
213                     __copy_to_user(&sregs_ext->vxrs_high,
214                                    current->thread.vxrs + __NUM_VXRS_LOW,
215                                    sizeof(sregs_ext->vxrs_high)))
216                         return -EFAULT;
217         }
218 #endif
219         return 0;
220 }
221 
222 static int restore_sigregs_ext(struct pt_regs *regs,
223                                _sigregs_ext __user *sregs_ext)
224 {
225 #ifdef CONFIG_64BIT
226         __u64 vxrs[__NUM_VXRS_LOW];
227         int i;
228 
229         /* Restore vector registers from signal stack */
230         if (current->thread.vxrs) {
231                 if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
232                                      sizeof(sregs_ext->vxrs_low)) ||
233                     __copy_from_user(current->thread.vxrs + __NUM_VXRS_LOW,
234                                      &sregs_ext->vxrs_high,
235                                      sizeof(sregs_ext->vxrs_high)))
236                         return -EFAULT;
237                 for (i = 0; i < __NUM_VXRS_LOW; i++)
238                         *((__u64 *)(current->thread.vxrs + i) + 1) = vxrs[i];
239         }
240 #endif
241         return 0;
242 }
243 
244 SYSCALL_DEFINE0(sigreturn)
245 {
246         struct pt_regs *regs = task_pt_regs(current);
247         struct sigframe __user *frame =
248                 (struct sigframe __user *) regs->gprs[15];
249         sigset_t set;
250 
251         if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
252                 goto badframe;
253         set_current_blocked(&set);
254         if (restore_sigregs(regs, &frame->sregs))
255                 goto badframe;
256         if (restore_sigregs_ext(regs, &frame->sregs_ext))
257                 goto badframe;
258         load_sigregs();
259         return regs->gprs[2];
260 badframe:
261         force_sig(SIGSEGV, current);
262         return 0;
263 }
264 
265 SYSCALL_DEFINE0(rt_sigreturn)
266 {
267         struct pt_regs *regs = task_pt_regs(current);
268         struct rt_sigframe __user *frame =
269                 (struct rt_sigframe __user *)regs->gprs[15];
270         sigset_t set;
271 
272         if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set)))
273                 goto badframe;
274         set_current_blocked(&set);
275         if (restore_altstack(&frame->uc.uc_stack))
276                 goto badframe;
277         if (restore_sigregs(regs, &frame->uc.uc_mcontext))
278                 goto badframe;
279         if (restore_sigregs_ext(regs, &frame->uc.uc_mcontext_ext))
280                 goto badframe;
281         load_sigregs();
282         return regs->gprs[2];
283 badframe:
284         force_sig(SIGSEGV, current);
285         return 0;
286 }
287 
288 /*
289  * Determine which stack to use..
290  */
291 static inline void __user *
292 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
293 {
294         unsigned long sp;
295 
296         /* Default to using normal stack */
297         sp = regs->gprs[15];
298 
299         /* Overflow on alternate signal stack gives SIGSEGV. */
300         if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
301                 return (void __user *) -1UL;
302 
303         /* This is the X/Open sanctioned signal stack switching.  */
304         if (ka->sa.sa_flags & SA_ONSTACK) {
305                 if (! sas_ss_flags(sp))
306                         sp = current->sas_ss_sp + current->sas_ss_size;
307         }
308 
309         return (void __user *)((sp - frame_size) & -8ul);
310 }
311 
312 static inline int map_signal(int sig)
313 {
314         if (current_thread_info()->exec_domain
315             && current_thread_info()->exec_domain->signal_invmap
316             && sig < 32)
317                 return current_thread_info()->exec_domain->signal_invmap[sig];
318         else
319                 return sig;
320 }
321 
322 static int setup_frame(int sig, struct k_sigaction *ka,
323                        sigset_t *set, struct pt_regs * regs)
324 {
325         struct sigframe __user *frame;
326         struct sigcontext sc;
327         unsigned long restorer;
328         size_t frame_size;
329 
330         /*
331          * gprs_high are only present for a 31-bit task running on
332          * a 64-bit kernel (see compat_signal.c) but the space for
333          * gprs_high need to be allocated if vector registers are
334          * included in the signal frame on a 31-bit system.
335          */
336         frame_size = sizeof(*frame) - sizeof(frame->sregs_ext);
337         if (MACHINE_HAS_VX)
338                 frame_size += sizeof(frame->sregs_ext);
339         frame = get_sigframe(ka, regs, frame_size);
340         if (frame == (void __user *) -1UL)
341                 return -EFAULT;
342 
343         /* Set up backchain. */
344         if (__put_user(regs->gprs[15], (addr_t __user *) frame))
345                 return -EFAULT;
346 
347         /* Create struct sigcontext on the signal stack */
348         memcpy(&sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE);
349         sc.sregs = (_sigregs __user __force *) &frame->sregs;
350         if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
351                 return -EFAULT;
352 
353         /* Store registers needed to create the signal frame */
354         store_sigregs();
355 
356         /* Create _sigregs on the signal stack */
357         if (save_sigregs(regs, &frame->sregs))
358                 return -EFAULT;
359 
360         /* Place signal number on stack to allow backtrace from handler.  */
361         if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
362                 return -EFAULT;
363 
364         /* Create _sigregs_ext on the signal stack */
365         if (save_sigregs_ext(regs, &frame->sregs_ext))
366                 return -EFAULT;
367 
368         /* Set up to return from userspace.  If provided, use a stub
369            already in userspace.  */
370         if (ka->sa.sa_flags & SA_RESTORER) {
371                 restorer = (unsigned long) ka->sa.sa_restorer | PSW_ADDR_AMODE;
372         } else {
373                 /* Signal frame without vector registers are short ! */
374                 __u16 __user *svc = (void __user *) frame + frame_size - 2;
375                 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
376                         return -EFAULT;
377                 restorer = (unsigned long) svc | PSW_ADDR_AMODE;
378         }
379 
380         /* Set up registers for signal handler */
381         regs->gprs[14] = restorer;
382         regs->gprs[15] = (unsigned long) frame;
383         /* Force default amode and default user address space control. */
384         regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
385                 (PSW_USER_BITS & PSW_MASK_ASC) |
386                 (regs->psw.mask & ~PSW_MASK_ASC);
387         regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
388 
389         regs->gprs[2] = map_signal(sig);
390         regs->gprs[3] = (unsigned long) &frame->sc;
391 
392         /* We forgot to include these in the sigcontext.
393            To avoid breaking binary compatibility, they are passed as args. */
394         if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
395             sig == SIGTRAP || sig == SIGFPE) {
396                 /* set extra registers only for synchronous signals */
397                 regs->gprs[4] = regs->int_code & 127;
398                 regs->gprs[5] = regs->int_parm_long;
399                 regs->gprs[6] = task_thread_info(current)->last_break;
400         }
401         return 0;
402 }
403 
404 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
405                           struct pt_regs *regs)
406 {
407         struct rt_sigframe __user *frame;
408         unsigned long uc_flags, restorer;
409         size_t frame_size;
410 
411         frame_size = sizeof(struct rt_sigframe) - sizeof(_sigregs_ext);
412         /*
413          * gprs_high are only present for a 31-bit task running on
414          * a 64-bit kernel (see compat_signal.c) but the space for
415          * gprs_high need to be allocated if vector registers are
416          * included in the signal frame on a 31-bit system.
417          */
418         uc_flags = 0;
419 #ifdef CONFIG_64BIT
420         if (MACHINE_HAS_VX) {
421                 frame_size += sizeof(_sigregs_ext);
422                 if (current->thread.vxrs)
423                         uc_flags |= UC_VXRS;
424         }
425 #endif
426         frame = get_sigframe(&ksig->ka, regs, frame_size);
427         if (frame == (void __user *) -1UL)
428                 return -EFAULT;
429 
430         /* Set up backchain. */
431         if (__put_user(regs->gprs[15], (addr_t __user *) frame))
432                 return -EFAULT;
433 
434         /* Set up to return from userspace.  If provided, use a stub
435            already in userspace.  */
436         if (ksig->ka.sa.sa_flags & SA_RESTORER) {
437                 restorer = (unsigned long)
438                         ksig->ka.sa.sa_restorer | PSW_ADDR_AMODE;
439         } else {
440                 __u16 __user *svc = &frame->svc_insn;
441                 if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))
442                         return -EFAULT;
443                 restorer = (unsigned long) svc | PSW_ADDR_AMODE;
444         }
445 
446         /* Create siginfo on the signal stack */
447         if (copy_siginfo_to_user(&frame->info, &ksig->info))
448                 return -EFAULT;
449 
450         /* Store registers needed to create the signal frame */
451         store_sigregs();
452 
453         /* Create ucontext on the signal stack. */
454         if (__put_user(uc_flags, &frame->uc.uc_flags) ||
455             __put_user(NULL, &frame->uc.uc_link) ||
456             __save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
457             save_sigregs(regs, &frame->uc.uc_mcontext) ||
458             __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)) ||
459             save_sigregs_ext(regs, &frame->uc.uc_mcontext_ext))
460                 return -EFAULT;
461 
462         /* Set up registers for signal handler */
463         regs->gprs[14] = restorer;
464         regs->gprs[15] = (unsigned long) frame;
465         /* Force default amode and default user address space control. */
466         regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
467                 (PSW_USER_BITS & PSW_MASK_ASC) |
468                 (regs->psw.mask & ~PSW_MASK_ASC);
469         regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler | PSW_ADDR_AMODE;
470 
471         regs->gprs[2] = map_signal(ksig->sig);
472         regs->gprs[3] = (unsigned long) &frame->info;
473         regs->gprs[4] = (unsigned long) &frame->uc;
474         regs->gprs[5] = task_thread_info(current)->last_break;
475         return 0;
476 }
477 
478 static void handle_signal(struct ksignal *ksig, sigset_t *oldset,
479                           struct pt_regs *regs)
480 {
481         int ret;
482 
483         /* Set up the stack frame */
484         if (ksig->ka.sa.sa_flags & SA_SIGINFO)
485                 ret = setup_rt_frame(ksig, oldset, regs);
486         else
487                 ret = setup_frame(ksig->sig, &ksig->ka, oldset, regs);
488 
489         signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
490 }
491 
492 /*
493  * Note that 'init' is a special process: it doesn't get signals it doesn't
494  * want to handle. Thus you cannot kill init even with a SIGKILL even by
495  * mistake.
496  *
497  * Note that we go through the signals twice: once to check the signals that
498  * the kernel can handle, and then we build all the user-level signal handling
499  * stack-frames in one go after that.
500  */
501 void do_signal(struct pt_regs *regs)
502 {
503         struct ksignal ksig;
504         sigset_t *oldset = sigmask_to_save();
505 
506         /*
507          * Get signal to deliver. When running under ptrace, at this point
508          * the debugger may change all our registers, including the system
509          * call information.
510          */
511         current_thread_info()->system_call =
512                 test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0;
513 
514         if (get_signal(&ksig)) {
515                 /* Whee!  Actually deliver the signal.  */
516                 if (current_thread_info()->system_call) {
517                         regs->int_code = current_thread_info()->system_call;
518                         /* Check for system call restarting. */
519                         switch (regs->gprs[2]) {
520                         case -ERESTART_RESTARTBLOCK:
521                         case -ERESTARTNOHAND:
522                                 regs->gprs[2] = -EINTR;
523                                 break;
524                         case -ERESTARTSYS:
525                                 if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
526                                         regs->gprs[2] = -EINTR;
527                                         break;
528                                 }
529                         /* fallthrough */
530                         case -ERESTARTNOINTR:
531                                 regs->gprs[2] = regs->orig_gpr2;
532                                 regs->psw.addr =
533                                         __rewind_psw(regs->psw,
534                                                      regs->int_code >> 16);
535                                 break;
536                         }
537                 }
538                 /* No longer in a system call */
539                 clear_pt_regs_flag(regs, PIF_SYSCALL);
540 
541                 if (is_compat_task())
542                         handle_signal32(&ksig, oldset, regs);
543                 else
544                         handle_signal(&ksig, oldset, regs);
545                 return;
546         }
547 
548         /* No handlers present - check for system call restart */
549         clear_pt_regs_flag(regs, PIF_SYSCALL);
550         if (current_thread_info()->system_call) {
551                 regs->int_code = current_thread_info()->system_call;
552                 switch (regs->gprs[2]) {
553                 case -ERESTART_RESTARTBLOCK:
554                         /* Restart with sys_restart_syscall */
555                         regs->int_code = __NR_restart_syscall;
556                 /* fallthrough */
557                 case -ERESTARTNOHAND:
558                 case -ERESTARTSYS:
559                 case -ERESTARTNOINTR:
560                         /* Restart system call with magic TIF bit. */
561                         regs->gprs[2] = regs->orig_gpr2;
562                         set_pt_regs_flag(regs, PIF_SYSCALL);
563                         if (test_thread_flag(TIF_SINGLE_STEP))
564                                 clear_pt_regs_flag(regs, PIF_PER_TRAP);
565                         break;
566                 }
567         }
568 
569         /*
570          * If there's no signal to deliver, we just put the saved sigmask back.
571          */
572         restore_saved_sigmask();
573 }
574 
575 void do_notify_resume(struct pt_regs *regs)
576 {
577         clear_thread_flag(TIF_NOTIFY_RESUME);
578         tracehook_notify_resume(regs);
579 }
580 

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