diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 13:38:45 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 13:38:45 -0700 |
commit | 38cb162b7585d837083b8365da1eb32687c5164c (patch) | |
tree | e4ae15715b23b320b1a92699fac767bc766c8f0b /arch/ia64/ia32 | |
parent | ba7cc09c9c9e29a57045dc5bbf843ac1cfad3283 (diff) | |
parent | e180583b85f4a48bd55924712c88e5d8eb182e08 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
[IA64] wire up pselect, ppoll
[IA64] Add TIF_RESTORE_SIGMASK
[IA64] unwind did not work for processes born with CLONE_STOPPED
[IA64] Optional method to purge the TLB on SN systems
[IA64] SPIN_LOCK_UNLOCKED macro cleanup in arch/ia64
[IA64-SN2][KJ] mmtimer.c-kzalloc
[IA64] fix stack alignment for ia32 signal handlers
[IA64] - Altix: hotplug after intr redirect can crash system
[IA64] save and restore cpus_allowed in cpu_idle_wait
[IA64] Removal of percpu TR cleanup in kexec code
[IA64] Fix some section mismatch errors
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 | 65 |
2 files changed, 16 insertions, 88 deletions
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index 687e5fdc968..99b665e2b1d 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S @@ -52,43 +52,6 @@ ENTRY(ia32_clone) br.ret.sptk.many rp END(ia32_clone) -ENTRY(sys32_rt_sigsuspend) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) - alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs - mov loc0=rp - mov out0=in0 // mask - mov out1=in1 // sigsetsize - mov out2=sp // out2 = &sigscratch - .fframe 16 - adds sp=-16,sp // allocate dummy "sigscratch" - ;; - .body - br.call.sptk.many rp=ia32_rt_sigsuspend -1: .restore sp - adds sp=16,sp - mov rp=loc0 - mov ar.pfs=loc1 - br.ret.sptk.many rp -END(sys32_rt_sigsuspend) - -ENTRY(sys32_sigsuspend) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) - alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs - mov loc0=rp - mov out0=in2 // mask (first two args are ignored) - ;; - mov out1=sp // out1 = &sigscratch - .fframe 16 - adds sp=-16,sp // allocate dummy "sigscratch" - .body - br.call.sptk.many rp=ia32_sigsuspend -1: .restore sp - adds sp=16,sp - mov rp=loc0 - mov ar.pfs=loc1 - br.ret.sptk.many rp -END(sys32_sigsuspend) - GLOBAL_ENTRY(ia32_ret_from_clone) PT_REGS_UNWIND_INFO(0) { /* @@ -389,7 +352,7 @@ ia32_syscall_table: data8 sys_rt_sigpending data8 compat_sys_rt_sigtimedwait data8 sys32_rt_sigqueueinfo - data8 sys32_rt_sigsuspend + data8 compat_sys_rt_sigsuspend data8 sys32_pread /* 180 */ data8 sys32_pwrite data8 sys_chown /* 16-bit version */ diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c index 10510e58520..85e82f32e48 100644 --- a/arch/ia64/ia32/ia32_signal.c +++ b/arch/ia64/ia32/ia32_signal.c @@ -451,59 +451,20 @@ sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int r sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); } -long -__ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr) +asmlinkage long +sys32_sigsuspend (int history0, int history1, old_sigset_t mask) { - extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall); - sigset_t oldset, set; - - scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */ - memset(&set, 0, sizeof(set)); - - memcpy(&set.sig, &sset->sig, sigsetsize); - - sigdelsetmask(&set, ~_BLOCKABLE); - + mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); - { - oldset = current->blocked; - current->blocked = set; - recalc_sigpending(); - } + current->saved_sigmask = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - /* - * The return below usually returns to the signal handler. We need to pre-set the - * correct error code here to ensure that the right values get saved in sigcontext - * by ia64_do_signal. - */ - scr->pt.r8 = -EINTR; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (ia64_do_signal(&oldset, scr, 1)) - return -EINTR; - } -} - -asmlinkage long -ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr) -{ - compat_sigset_t set; - - if (sigsetsize > sizeof(compat_sigset_t)) - return -EINVAL; - - if (copy_from_user(&set.sig, &uset->sig, sigsetsize)) - return -EFAULT; - - return __ia32_rt_sigsuspend(&set, sigsetsize, scr); -} - -asmlinkage long -ia32_sigsuspend (unsigned int mask, struct sigscratch *scr) -{ - return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr); + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } asmlinkage long @@ -810,7 +771,11 @@ get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) } /* Legacy stack switching not supported */ - return (void __user *)((esp - frame_size) & -8ul); + esp -= frame_size; + /* Align the stack pointer according to the i386 ABI, + * i.e. so that on function entry ((sp + 4) & 15) == 0. */ + esp = ((esp + 4) & -16ul) - 4; + return (void __user *) esp; } static int |