linux/arch/s390/kernel/compat_signal.c
<<
>>
Prefs
   1/*
   2 *  arch/s390/kernel/compat_signal.c
   3 *
   4 *    Copyright (C) IBM Corp. 2000,2006
   5 *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
   6 *               Gerhard Tonn (ton@de.ibm.com)                  
   7 *
   8 *  Copyright (C) 1991, 1992  Linus Torvalds
   9 *
  10 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
  11 */
  12
  13#include <linux/compat.h>
  14#include <linux/sched.h>
  15#include <linux/mm.h>
  16#include <linux/smp.h>
  17#include <linux/kernel.h>
  18#include <linux/signal.h>
  19#include <linux/errno.h>
  20#include <linux/wait.h>
  21#include <linux/ptrace.h>
  22#include <linux/unistd.h>
  23#include <linux/stddef.h>
  24#include <linux/tty.h>
  25#include <linux/personality.h>
  26#include <linux/binfmts.h>
  27#include <asm/ucontext.h>
  28#include <asm/uaccess.h>
  29#include <asm/lowcore.h>
  30#include "compat_linux.h"
  31#include "compat_ptrace.h"
  32#include "entry.h"
  33
  34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  35
  36typedef struct 
  37{
  38        __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
  39        struct sigcontext32 sc;
  40        _sigregs32 sregs;
  41        int signo;
  42        __u8 retcode[S390_SYSCALL_SIZE];
  43} sigframe32;
  44
  45typedef struct 
  46{
  47        __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
  48        __u8 retcode[S390_SYSCALL_SIZE];
  49        compat_siginfo_t info;
  50        struct ucontext32 uc;
  51} rt_sigframe32;
  52
  53int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
  54{
  55        int err;
  56
  57        if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
  58                return -EFAULT;
  59
  60        /* If you change siginfo_t structure, please be sure
  61           this code is fixed accordingly.
  62           It should never copy any pad contained in the structure
  63           to avoid security leaks, but must copy the generic
  64           3 ints plus the relevant union member.  
  65           This routine must convert siginfo from 64bit to 32bit as well
  66           at the same time.  */
  67        err = __put_user(from->si_signo, &to->si_signo);
  68        err |= __put_user(from->si_errno, &to->si_errno);
  69        err |= __put_user((short)from->si_code, &to->si_code);
  70        if (from->si_code < 0)
  71                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
  72        else {
  73                switch (from->si_code >> 16) {
  74                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
  75                case __SI_MESGQ >> 16:
  76                        err |= __put_user(from->si_int, &to->si_int);
  77                        /* fallthrough */
  78                case __SI_KILL >> 16:
  79                        err |= __put_user(from->si_pid, &to->si_pid);
  80                        err |= __put_user(from->si_uid, &to->si_uid);
  81                        break;
  82                case __SI_CHLD >> 16:
  83                        err |= __put_user(from->si_pid, &to->si_pid);
  84                        err |= __put_user(from->si_uid, &to->si_uid);
  85                        err |= __put_user(from->si_utime, &to->si_utime);
  86                        err |= __put_user(from->si_stime, &to->si_stime);
  87                        err |= __put_user(from->si_status, &to->si_status);
  88                        break;
  89                case __SI_FAULT >> 16:
  90                        err |= __put_user((unsigned long) from->si_addr,
  91                                          &to->si_addr);
  92                        break;
  93                case __SI_POLL >> 16:
  94                        err |= __put_user(from->si_band, &to->si_band);
  95                        err |= __put_user(from->si_fd, &to->si_fd);
  96                        break;
  97                case __SI_TIMER >> 16:
  98                        err |= __put_user(from->si_tid, &to->si_tid);
  99                        err |= __put_user(from->si_overrun, &to->si_overrun);
 100                        err |= __put_user(from->si_int, &to->si_int);
 101                        break;
 102                default:
 103                        break;
 104                }
 105        }
 106        return err;
 107}
 108
 109int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 110{
 111        int err;
 112        u32 tmp;
 113
 114        if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t)))
 115                return -EFAULT;
 116
 117        err = __get_user(to->si_signo, &from->si_signo);
 118        err |= __get_user(to->si_errno, &from->si_errno);
 119        err |= __get_user(to->si_code, &from->si_code);
 120
 121        if (to->si_code < 0)
 122                err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 123        else {
 124                switch (to->si_code >> 16) {
 125                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 126                case __SI_MESGQ >> 16:
 127                        err |= __get_user(to->si_int, &from->si_int);
 128                        /* fallthrough */
 129                case __SI_KILL >> 16:
 130                        err |= __get_user(to->si_pid, &from->si_pid);
 131                        err |= __get_user(to->si_uid, &from->si_uid);
 132                        break;
 133                case __SI_CHLD >> 16:
 134                        err |= __get_user(to->si_pid, &from->si_pid);
 135                        err |= __get_user(to->si_uid, &from->si_uid);
 136                        err |= __get_user(to->si_utime, &from->si_utime);
 137                        err |= __get_user(to->si_stime, &from->si_stime);
 138                        err |= __get_user(to->si_status, &from->si_status);
 139                        break;
 140                case __SI_FAULT >> 16:
 141                        err |= __get_user(tmp, &from->si_addr);
 142                        to->si_addr = (void __user *)(u64) (tmp & PSW32_ADDR_INSN);
 143                        break;
 144                case __SI_POLL >> 16:
 145                        err |= __get_user(to->si_band, &from->si_band);
 146                        err |= __get_user(to->si_fd, &from->si_fd);
 147                        break;
 148                case __SI_TIMER >> 16:
 149                        err |= __get_user(to->si_tid, &from->si_tid);
 150                        err |= __get_user(to->si_overrun, &from->si_overrun);
 151                        err |= __get_user(to->si_int, &from->si_int);
 152                        break;
 153                default:
 154                        break;
 155                }
 156        }
 157        return err;
 158}
 159
 160asmlinkage long
 161sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
 162                 struct old_sigaction32 __user *oact)
 163{
 164        struct k_sigaction new_ka, old_ka;
 165        unsigned long sa_handler, sa_restorer;
 166        int ret;
 167
 168        if (act) {
 169                compat_old_sigset_t mask;
 170                if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
 171                    __get_user(sa_handler, &act->sa_handler) ||
 172                    __get_user(sa_restorer, &act->sa_restorer) ||
 173                    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
 174                    __get_user(mask, &act->sa_mask))
 175                        return -EFAULT;
 176                new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
 177                new_ka.sa.sa_restorer = (void (*)(void)) sa_restorer;
 178                siginitset(&new_ka.sa.sa_mask, mask);
 179        }
 180
 181        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 182
 183        if (!ret && oact) {
 184                sa_handler = (unsigned long) old_ka.sa.sa_handler;
 185                sa_restorer = (unsigned long) old_ka.sa.sa_restorer;
 186                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
 187                    __put_user(sa_handler, &oact->sa_handler) ||
 188                    __put_user(sa_restorer, &oact->sa_restorer) ||
 189                    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
 190                    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
 191                        return -EFAULT;
 192        }
 193
 194        return ret;
 195}
 196
 197asmlinkage long
 198sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
 199           struct sigaction32 __user *oact,  size_t sigsetsize)
 200{
 201        struct k_sigaction new_ka, old_ka;
 202        unsigned long sa_handler;
 203        int ret;
 204        compat_sigset_t set32;
 205
 206        /* XXX: Don't preclude handling different sized sigset_t's.  */
 207        if (sigsetsize != sizeof(compat_sigset_t))
 208                return -EINVAL;
 209
 210        if (act) {
 211                ret = get_user(sa_handler, &act->sa_handler);
 212                ret |= __copy_from_user(&set32, &act->sa_mask,
 213                                        sizeof(compat_sigset_t));
 214                switch (_NSIG_WORDS) {
 215                case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
 216                                | (((long)set32.sig[7]) << 32);
 217                case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
 218                                | (((long)set32.sig[5]) << 32);
 219                case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
 220                                | (((long)set32.sig[3]) << 32);
 221                case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
 222                                | (((long)set32.sig[1]) << 32);
 223                }
 224                ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 225                
 226                if (ret)
 227                        return -EFAULT;
 228                new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
 229        }
 230
 231        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 232
 233        if (!ret && oact) {
 234                switch (_NSIG_WORDS) {
 235                case 4:
 236                        set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
 237                        set32.sig[6] = old_ka.sa.sa_mask.sig[3];
 238                case 3:
 239                        set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
 240                        set32.sig[4] = old_ka.sa.sa_mask.sig[2];
 241                case 2:
 242                        set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
 243                        set32.sig[2] = old_ka.sa.sa_mask.sig[1];
 244                case 1:
 245                        set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
 246                        set32.sig[0] = old_ka.sa.sa_mask.sig[0];
 247                }
 248                ret = put_user((unsigned long)old_ka.sa.sa_handler, &oact->sa_handler);
 249                ret |= __copy_to_user(&oact->sa_mask, &set32,
 250                                      sizeof(compat_sigset_t));
 251                ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 252        }
 253
 254        return ret;
 255}
 256
 257asmlinkage long
 258sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss)
 259{
 260        struct pt_regs *regs = task_pt_regs(current);
 261        stack_t kss, koss;
 262        unsigned long ss_sp;
 263        int ret, err = 0;
 264        mm_segment_t old_fs = get_fs();
 265
 266        if (uss) {
 267                if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
 268                        return -EFAULT;
 269                err |= __get_user(ss_sp, &uss->ss_sp);
 270                err |= __get_user(kss.ss_size, &uss->ss_size);
 271                err |= __get_user(kss.ss_flags, &uss->ss_flags);
 272                if (err)
 273                        return -EFAULT;
 274                kss.ss_sp = (void __user *) ss_sp;
 275        }
 276
 277        set_fs (KERNEL_DS);
 278        ret = do_sigaltstack((stack_t __force __user *) (uss ? &kss : NULL),
 279                             (stack_t __force __user *) (uoss ? &koss : NULL),
 280                             regs->gprs[15]);
 281        set_fs (old_fs);
 282
 283        if (!ret && uoss) {
 284                if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
 285                        return -EFAULT;
 286                ss_sp = (unsigned long) koss.ss_sp;
 287                err |= __put_user(ss_sp, &uoss->ss_sp);
 288                err |= __put_user(koss.ss_size, &uoss->ss_size);
 289                err |= __put_user(koss.ss_flags, &uoss->ss_flags);
 290                if (err)
 291                        return -EFAULT;
 292        }
 293        return ret;
 294}
 295
 296static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
 297{
 298        _s390_regs_common32 regs32;
 299        int err, i;
 300
 301        regs32.psw.mask = PSW32_MASK_MERGE(psw32_user_bits,
 302                                           (__u32)(regs->psw.mask >> 32));
 303        regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
 304        for (i = 0; i < NUM_GPRS; i++)
 305                regs32.gprs[i] = (__u32) regs->gprs[i];
 306        save_access_regs(current->thread.acrs);
 307        memcpy(regs32.acrs, current->thread.acrs, sizeof(regs32.acrs));
 308        err = __copy_to_user(&sregs->regs, &regs32, sizeof(regs32));
 309        if (err)
 310                return err;
 311        save_fp_regs(&current->thread.fp_regs);
 312        /* s390_fp_regs and _s390_fp_regs32 are the same ! */
 313        return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
 314                              sizeof(_s390_fp_regs32));
 315}
 316
 317static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
 318{
 319        _s390_regs_common32 regs32;
 320        int err, i;
 321
 322        /* Alwys make any pending restarted system call return -EINTR */
 323        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 324
 325        err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
 326        if (err)
 327                return err;
 328        regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
 329                                        (__u64)regs32.psw.mask << 32);
 330        regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
 331        for (i = 0; i < NUM_GPRS; i++)
 332                regs->gprs[i] = (__u64) regs32.gprs[i];
 333        memcpy(current->thread.acrs, regs32.acrs, sizeof(current->thread.acrs));
 334        restore_access_regs(current->thread.acrs);
 335
 336        err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs,
 337                               sizeof(_s390_fp_regs32));
 338        current->thread.fp_regs.fpc &= FPC_VALID_MASK;
 339        if (err)
 340                return err;
 341
 342        restore_fp_regs(&current->thread.fp_regs);
 343        regs->svcnr = 0;        /* disable syscall checks */
 344        return 0;
 345}
 346
 347asmlinkage long sys32_sigreturn(void)
 348{
 349        struct pt_regs *regs = task_pt_regs(current);
 350        sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
 351        sigset_t set;
 352
 353        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 354                goto badframe;
 355        if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
 356                goto badframe;
 357
 358        sigdelsetmask(&set, ~_BLOCKABLE);
 359        spin_lock_irq(&current->sighand->siglock);
 360        current->blocked = set;
 361        recalc_sigpending();
 362        spin_unlock_irq(&current->sighand->siglock);
 363
 364        if (restore_sigregs32(regs, &frame->sregs))
 365                goto badframe;
 366
 367        return regs->gprs[2];
 368
 369badframe:
 370        force_sig(SIGSEGV, current);
 371        return 0;
 372}
 373
 374asmlinkage long sys32_rt_sigreturn(void)
 375{
 376        struct pt_regs *regs = task_pt_regs(current);
 377        rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
 378        sigset_t set;
 379        stack_t st;
 380        __u32 ss_sp;
 381        int err;
 382        mm_segment_t old_fs = get_fs();
 383
 384        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 385                goto badframe;
 386        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 387                goto badframe;
 388
 389        sigdelsetmask(&set, ~_BLOCKABLE);
 390        spin_lock_irq(&current->sighand->siglock);
 391        current->blocked = set;
 392        recalc_sigpending();
 393        spin_unlock_irq(&current->sighand->siglock);
 394
 395        if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
 396                goto badframe;
 397
 398        err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
 399        st.ss_sp = compat_ptr(ss_sp);
 400        err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size);
 401        err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
 402        if (err)
 403                goto badframe; 
 404
 405        set_fs (KERNEL_DS);
 406        do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]);
 407        set_fs (old_fs);
 408
 409        return regs->gprs[2];
 410
 411badframe:
 412        force_sig(SIGSEGV, current);
 413        return 0;
 414}       
 415
 416/*
 417 * Set up a signal frame.
 418 */
 419
 420
 421/*
 422 * Determine which stack to use..
 423 */
 424static inline void __user *
 425get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
 426{
 427        unsigned long sp;
 428
 429        /* Default to using normal stack */
 430        sp = (unsigned long) A(regs->gprs[15]);
 431
 432        /* Overflow on alternate signal stack gives SIGSEGV. */
 433        if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
 434                return (void __user *) -1UL;
 435
 436        /* This is the X/Open sanctioned signal stack switching.  */
 437        if (ka->sa.sa_flags & SA_ONSTACK) {
 438                if (! sas_ss_flags(sp))
 439                        sp = current->sas_ss_sp + current->sas_ss_size;
 440        }
 441
 442        /* This is the legacy signal stack switching. */
 443        else if (!user_mode(regs) &&
 444                 !(ka->sa.sa_flags & SA_RESTORER) &&
 445                 ka->sa.sa_restorer) {
 446                sp = (unsigned long) ka->sa.sa_restorer;
 447        }
 448
 449        return (void __user *)((sp - frame_size) & -8ul);
 450}
 451
 452static inline int map_signal(int sig)
 453{
 454        if (current_thread_info()->exec_domain
 455            && current_thread_info()->exec_domain->signal_invmap
 456            && sig < 32)
 457                return current_thread_info()->exec_domain->signal_invmap[sig];
 458        else
 459                return sig;
 460}
 461
 462static int setup_frame32(int sig, struct k_sigaction *ka,
 463                        sigset_t *set, struct pt_regs * regs)
 464{
 465        sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
 466        if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
 467                goto give_sigsegv;
 468
 469        if (frame == (void __user *) -1UL)
 470                goto give_sigsegv;
 471
 472        if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
 473                goto give_sigsegv;
 474
 475        if (save_sigregs32(regs, &frame->sregs))
 476                goto give_sigsegv;
 477        if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
 478                goto give_sigsegv;
 479
 480        /* Set up to return from userspace.  If provided, use a stub
 481           already in userspace.  */
 482        if (ka->sa.sa_flags & SA_RESTORER) {
 483                regs->gprs[14] = (__u64) ka->sa.sa_restorer;
 484        } else {
 485                regs->gprs[14] = (__u64) frame->retcode;
 486                if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
 487                               (u16 __user *)(frame->retcode)))
 488                        goto give_sigsegv;
 489        }
 490
 491        /* Set up backchain. */
 492        if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
 493                goto give_sigsegv;
 494
 495        /* Set up registers for signal handler */
 496        regs->gprs[15] = (__u64) frame;
 497        regs->psw.addr = (__u64) ka->sa.sa_handler;
 498
 499        regs->gprs[2] = map_signal(sig);
 500        regs->gprs[3] = (__u64) &frame->sc;
 501
 502        /* We forgot to include these in the sigcontext.
 503           To avoid breaking binary compatibility, they are passed as args. */
 504        regs->gprs[4] = current->thread.trap_no;
 505        regs->gprs[5] = current->thread.prot_addr;
 506
 507        /* Place signal number on stack to allow backtrace from handler.  */
 508        if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
 509                goto give_sigsegv;
 510        return 0;
 511
 512give_sigsegv:
 513        force_sigsegv(sig, current);
 514        return -EFAULT;
 515}
 516
 517static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
 518                           sigset_t *set, struct pt_regs * regs)
 519{
 520        int err = 0;
 521        rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
 522        if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
 523                goto give_sigsegv;
 524
 525        if (frame == (void __user *) -1UL)
 526                goto give_sigsegv;
 527
 528        if (copy_siginfo_to_user32(&frame->info, info))
 529                goto give_sigsegv;
 530
 531        /* Create the ucontext.  */
 532        err |= __put_user(0, &frame->uc.uc_flags);
 533        err |= __put_user(0, &frame->uc.uc_link);
 534        err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
 535        err |= __put_user(sas_ss_flags(regs->gprs[15]),
 536                          &frame->uc.uc_stack.ss_flags);
 537        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
 538        err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
 539        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 540        if (err)
 541                goto give_sigsegv;
 542
 543        /* Set up to return from userspace.  If provided, use a stub
 544           already in userspace.  */
 545        if (ka->sa.sa_flags & SA_RESTORER) {
 546                regs->gprs[14] = (__u64) ka->sa.sa_restorer;
 547        } else {
 548                regs->gprs[14] = (__u64) frame->retcode;
 549                err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
 550                                  (u16 __user *)(frame->retcode));
 551        }
 552
 553        /* Set up backchain. */
 554        if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
 555                goto give_sigsegv;
 556
 557        /* Set up registers for signal handler */
 558        regs->gprs[15] = (__u64) frame;
 559        regs->psw.addr = (__u64) ka->sa.sa_handler;
 560
 561        regs->gprs[2] = map_signal(sig);
 562        regs->gprs[3] = (__u64) &frame->info;
 563        regs->gprs[4] = (__u64) &frame->uc;
 564        return 0;
 565
 566give_sigsegv:
 567        force_sigsegv(sig, current);
 568        return -EFAULT;
 569}
 570
 571/*
 572 * OK, we're invoking a handler
 573 */     
 574
 575int
 576handle_signal32(unsigned long sig, struct k_sigaction *ka,
 577                siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 578{
 579        int ret;
 580
 581        /* Set up the stack frame */
 582        if (ka->sa.sa_flags & SA_SIGINFO)
 583                ret = setup_rt_frame32(sig, ka, info, oldset, regs);
 584        else
 585                ret = setup_frame32(sig, ka, oldset, regs);
 586
 587        if (ret == 0) {
 588                spin_lock_irq(&current->sighand->siglock);
 589                sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 590                if (!(ka->sa.sa_flags & SA_NODEFER))
 591                        sigaddset(&current->blocked,sig);
 592                recalc_sigpending();
 593                spin_unlock_irq(&current->sighand->siglock);
 594        }
 595        return ret;
 596}
 597
 598