diff options
author | Alexey Dobriyan <adobriyan@openvz.org> | 2007-01-23 11:03:17 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2007-05-08 17:51:59 -0400 |
commit | 4a177cbf84f827cf9f1d6cfa5264fafd3cc33ce0 (patch) | |
tree | ef04ada4e2b708ee965081cd905026c9156863d3 /arch/ia64/ia32 | |
parent | 690def21414fa43fac1b8053fd952c0366c476de (diff) |
[IA64] Add TIF_RESTORE_SIGMASK
Preparation for pselect and ppoll.
ia32 compat code not tested. :-(
Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Signed-off-by: Alexey Dobriyan <adobriyan@openvz.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/ia32')
-rw-r--r-- | arch/ia64/ia32/ia32_entry.S | 39 | ||||
-rw-r--r-- | arch/ia64/ia32/ia32_signal.c | 59 |
2 files changed, 11 insertions, 87 deletions
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index 687e5fdc9683..99b665e2b1d5 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S | |||
@@ -52,43 +52,6 @@ ENTRY(ia32_clone) | |||
52 | br.ret.sptk.many rp | 52 | br.ret.sptk.many rp |
53 | END(ia32_clone) | 53 | END(ia32_clone) |
54 | 54 | ||
55 | ENTRY(sys32_rt_sigsuspend) | ||
56 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) | ||
57 | alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs | ||
58 | mov loc0=rp | ||
59 | mov out0=in0 // mask | ||
60 | mov out1=in1 // sigsetsize | ||
61 | mov out2=sp // out2 = &sigscratch | ||
62 | .fframe 16 | ||
63 | adds sp=-16,sp // allocate dummy "sigscratch" | ||
64 | ;; | ||
65 | .body | ||
66 | br.call.sptk.many rp=ia32_rt_sigsuspend | ||
67 | 1: .restore sp | ||
68 | adds sp=16,sp | ||
69 | mov rp=loc0 | ||
70 | mov ar.pfs=loc1 | ||
71 | br.ret.sptk.many rp | ||
72 | END(sys32_rt_sigsuspend) | ||
73 | |||
74 | ENTRY(sys32_sigsuspend) | ||
75 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) | ||
76 | alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs | ||
77 | mov loc0=rp | ||
78 | mov out0=in2 // mask (first two args are ignored) | ||
79 | ;; | ||
80 | mov out1=sp // out1 = &sigscratch | ||
81 | .fframe 16 | ||
82 | adds sp=-16,sp // allocate dummy "sigscratch" | ||
83 | .body | ||
84 | br.call.sptk.many rp=ia32_sigsuspend | ||
85 | 1: .restore sp | ||
86 | adds sp=16,sp | ||
87 | mov rp=loc0 | ||
88 | mov ar.pfs=loc1 | ||
89 | br.ret.sptk.many rp | ||
90 | END(sys32_sigsuspend) | ||
91 | |||
92 | GLOBAL_ENTRY(ia32_ret_from_clone) | 55 | GLOBAL_ENTRY(ia32_ret_from_clone) |
93 | PT_REGS_UNWIND_INFO(0) | 56 | PT_REGS_UNWIND_INFO(0) |
94 | { /* | 57 | { /* |
@@ -389,7 +352,7 @@ ia32_syscall_table: | |||
389 | data8 sys_rt_sigpending | 352 | data8 sys_rt_sigpending |
390 | data8 compat_sys_rt_sigtimedwait | 353 | data8 compat_sys_rt_sigtimedwait |
391 | data8 sys32_rt_sigqueueinfo | 354 | data8 sys32_rt_sigqueueinfo |
392 | data8 sys32_rt_sigsuspend | 355 | data8 compat_sys_rt_sigsuspend |
393 | data8 sys32_pread /* 180 */ | 356 | data8 sys32_pread /* 180 */ |
394 | data8 sys32_pwrite | 357 | data8 sys32_pwrite |
395 | data8 sys_chown /* 16-bit version */ | 358 | data8 sys_chown /* 16-bit version */ |
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c index 7b38b73e7827..b2bb7f227920 100644 --- a/arch/ia64/ia32/ia32_signal.c +++ b/arch/ia64/ia32/ia32_signal.c | |||
@@ -452,59 +452,20 @@ sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int r | |||
452 | sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); | 452 | sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); |
453 | } | 453 | } |
454 | 454 | ||
455 | long | 455 | asmlinkage long |
456 | __ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr) | 456 | sys32_sigsuspend (int history0, int history1, old_sigset_t mask) |
457 | { | 457 | { |
458 | extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall); | 458 | mask &= _BLOCKABLE; |
459 | sigset_t oldset, set; | ||
460 | |||
461 | scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */ | ||
462 | memset(&set, 0, sizeof(set)); | ||
463 | |||
464 | memcpy(&set.sig, &sset->sig, sigsetsize); | ||
465 | |||
466 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
467 | |||
468 | spin_lock_irq(¤t->sighand->siglock); | 459 | spin_lock_irq(¤t->sighand->siglock); |
469 | { | 460 | current->saved_sigmask = current->blocked; |
470 | oldset = current->blocked; | 461 | siginitset(¤t->blocked, mask); |
471 | current->blocked = set; | 462 | recalc_sigpending(); |
472 | recalc_sigpending(); | ||
473 | } | ||
474 | spin_unlock_irq(¤t->sighand->siglock); | 463 | spin_unlock_irq(¤t->sighand->siglock); |
475 | 464 | ||
476 | /* | 465 | current->state = TASK_INTERRUPTIBLE; |
477 | * The return below usually returns to the signal handler. We need to pre-set the | 466 | schedule(); |
478 | * correct error code here to ensure that the right values get saved in sigcontext | 467 | set_thread_flag(TIF_RESTORE_SIGMASK); |
479 | * by ia64_do_signal. | 468 | return -ERESTARTNOHAND; |
480 | */ | ||
481 | scr->pt.r8 = -EINTR; | ||
482 | while (1) { | ||
483 | current->state = TASK_INTERRUPTIBLE; | ||
484 | schedule(); | ||
485 | if (ia64_do_signal(&oldset, scr, 1)) | ||
486 | return -EINTR; | ||
487 | } | ||
488 | } | ||
489 | |||
490 | asmlinkage long | ||
491 | ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr) | ||
492 | { | ||
493 | compat_sigset_t set; | ||
494 | |||
495 | if (sigsetsize > sizeof(compat_sigset_t)) | ||
496 | return -EINVAL; | ||
497 | |||
498 | if (copy_from_user(&set.sig, &uset->sig, sigsetsize)) | ||
499 | return -EFAULT; | ||
500 | |||
501 | return __ia32_rt_sigsuspend(&set, sigsetsize, scr); | ||
502 | } | ||
503 | |||
504 | asmlinkage long | ||
505 | ia32_sigsuspend (unsigned int mask, struct sigscratch *scr) | ||
506 | { | ||
507 | return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr); | ||
508 | } | 469 | } |
509 | 470 | ||
510 | asmlinkage long | 471 | asmlinkage long |