linux/arch/s390/kernel/compat_signal.c
<<
>>
Prefs
   1/*
   2 *    Copyright IBM Corp. 2000, 2006
   3 *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
   4 *               Gerhard Tonn (ton@de.ibm.com)                  
   5 *
   6 *  Copyright (C) 1991, 1992  Linus Torvalds
   7 *
   8 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
   9 */
  10
  11#include <linux/compat.h>
  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 <asm/ucontext.h>
  26#include <asm/uaccess.h>
  27#include <asm/lowcore.h>
  28#include <asm/switch_to.h>
  29#include "compat_linux.h"
  30#include "compat_ptrace.h"
  31#include "entry.h"
  32
  33typedef struct 
  34{
  35        __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
  36        struct sigcontext32 sc;
  37        _sigregs32 sregs;
  38        int signo;
  39        _sigregs_ext32 sregs_ext;
  40        __u16 svc_insn;         /* Offset of svc_insn is NOT fixed! */
  41} sigframe32;
  42
  43typedef struct 
  44{
  45        __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
  46        __u16 svc_insn;
  47        compat_siginfo_t info;
  48        struct ucontext32 uc;
  49} rt_sigframe32;
  50
  51static inline void sigset_to_sigset32(unsigned long *set64,
  52                                      compat_sigset_word *set32)
  53{
  54        set32[0] = (compat_sigset_word) set64[0];
  55        set32[1] = (compat_sigset_word)(set64[0] >> 32);
  56}
  57
  58static inline void sigset32_to_sigset(compat_sigset_word *set32,
  59                                      unsigned long *set64)
  60{
  61        set64[0] = (unsigned long) set32[0] | ((unsigned long) set32[1] << 32);
  62}
  63
  64int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
  65{
  66        int err;
  67
  68        /* If you change siginfo_t structure, please be sure
  69           this code is fixed accordingly.
  70           It should never copy any pad contained in the structure
  71           to avoid security leaks, but must copy the generic
  72           3 ints plus the relevant union member.  
  73           This routine must convert siginfo from 64bit to 32bit as well
  74           at the same time.  */
  75        err = __put_user(from->si_signo, &to->si_signo);
  76        err |= __put_user(from->si_errno, &to->si_errno);
  77        err |= __put_user((short)from->si_code, &to->si_code);
  78        if (from->si_code < 0)
  79                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
  80        else {
  81                switch (from->si_code >> 16) {
  82                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
  83                case __SI_MESGQ >> 16:
  84                        err |= __put_user(from->si_int, &to->si_int);
  85                        /* fallthrough */
  86                case __SI_KILL >> 16:
  87                        err |= __put_user(from->si_pid, &to->si_pid);
  88                        err |= __put_user(from->si_uid, &to->si_uid);
  89                        break;
  90                case __SI_CHLD >> 16:
  91                        err |= __put_user(from->si_pid, &to->si_pid);
  92                        err |= __put_user(from->si_uid, &to->si_uid);
  93                        err |= __put_user(from->si_utime, &to->si_utime);
  94                        err |= __put_user(from->si_stime, &to->si_stime);
  95                        err |= __put_user(from->si_status, &to->si_status);
  96                        break;
  97                case __SI_FAULT >> 16:
  98                        err |= __put_user((unsigned long) from->si_addr,
  99                                          &to->si_addr);
 100                        break;
 101                case __SI_POLL >> 16:
 102                        err |= __put_user(from->si_band, &to->si_band);
 103                        err |= __put_user(from->si_fd, &to->si_fd);
 104                        break;
 105                case __SI_TIMER >> 16:
 106                        err |= __put_user(from->si_tid, &to->si_tid);
 107                        err |= __put_user(from->si_overrun, &to->si_overrun);
 108                        err |= __put_user(from->si_int, &to->si_int);
 109                        break;
 110                default:
 111                        break;
 112                }
 113        }
 114        return err;
 115}
 116
 117int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 118{
 119        int err;
 120        u32 tmp;
 121
 122        err = __get_user(to->si_signo, &from->si_signo);
 123        err |= __get_user(to->si_errno, &from->si_errno);
 124        err |= __get_user(to->si_code, &from->si_code);
 125
 126        if (to->si_code < 0)
 127                err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 128        else {
 129                switch (to->si_code >> 16) {
 130                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 131                case __SI_MESGQ >> 16:
 132                        err |= __get_user(to->si_int, &from->si_int);
 133                        /* fallthrough */
 134                case __SI_KILL >> 16:
 135                        err |= __get_user(to->si_pid, &from->si_pid);
 136                        err |= __get_user(to->si_uid, &from->si_uid);
 137                        break;
 138                case __SI_CHLD >> 16:
 139                        err |= __get_user(to->si_pid, &from->si_pid);
 140                        err |= __get_user(to->si_uid, &from->si_uid);
 141                        err |= __get_user(to->si_utime, &from->si_utime);
 142                        err |= __get_user(to->si_stime, &from->si_stime);
 143                        err |= __get_user(to->si_status, &from->si_status);
 144                        break;
 145                case __SI_FAULT >> 16:
 146                        err |= __get_user(tmp, &from->si_addr);
 147                        to->si_addr = (void __force __user *)
 148                                (u64) (tmp & PSW32_ADDR_INSN);
 149                        break;
 150                case __SI_POLL >> 16:
 151                        err |= __get_user(to->si_band, &from->si_band);
 152                        err |= __get_user(to->si_fd, &from->si_fd);
 153                        break;
 154                case __SI_TIMER >> 16:
 155                        err |= __get_user(to->si_tid, &from->si_tid);
 156                        err |= __get_user(to->si_overrun, &from->si_overrun);
 157                        err |= __get_user(to->si_int, &from->si_int);
 158                        break;
 159                default:
 160                        break;
 161                }
 162        }
 163        return err;
 164}
 165
 166/* Store registers needed to create the signal frame */
 167static void store_sigregs(void)
 168{
 169        int i;
 170
 171        save_access_regs(current->thread.acrs);
 172        save_fp_ctl(&current->thread.fp_regs.fpc);
 173        if (current->thread.vxrs) {
 174                save_vx_regs(current->thread.vxrs);
 175                for (i = 0; i < __NUM_FPRS; i++)
 176                        current->thread.fp_regs.fprs[i] =
 177                                *(freg_t *)(current->thread.vxrs + i);
 178        } else
 179                save_fp_regs(current->thread.fp_regs.fprs);
 180}
 181
 182/* Load registers after signal return */
 183static void load_sigregs(void)
 184{
 185        int i;
 186
 187        restore_access_regs(current->thread.acrs);
 188        /* restore_fp_ctl is done in restore_sigregs */
 189        if (current->thread.vxrs) {
 190                for (i = 0; i < __NUM_FPRS; i++)
 191                        *(freg_t *)(current->thread.vxrs + i) =
 192                                current->thread.fp_regs.fprs[i];
 193                restore_vx_regs(current->thread.vxrs);
 194        } else
 195                restore_fp_regs(current->thread.fp_regs.fprs);
 196}
 197
 198static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
 199{
 200        _sigregs32 user_sregs;
 201        int i;
 202
 203        user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32);
 204        user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI;
 205        user_sregs.regs.psw.mask |= PSW32_USER_BITS;
 206        user_sregs.regs.psw.addr = (__u32) regs->psw.addr |
 207                (__u32)(regs->psw.mask & PSW_MASK_BA);
 208        for (i = 0; i < NUM_GPRS; i++)
 209                user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
 210        memcpy(&user_sregs.regs.acrs, current->thread.acrs,
 211               sizeof(user_sregs.regs.acrs));
 212        memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
 213               sizeof(user_sregs.fpregs));
 214        if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
 215                return -EFAULT;
 216        return 0;
 217}
 218
 219static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
 220{
 221        _sigregs32 user_sregs;
 222        int i;
 223
 224        /* Alwys make any pending restarted system call return -EINTR */
 225        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 226
 227        if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
 228                return -EFAULT;
 229
 230        if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI))
 231                return -EINVAL;
 232
 233        /* Loading the floating-point-control word can fail. Do that first. */
 234        if (restore_fp_ctl(&user_sregs.fpregs.fpc))
 235                return -EINVAL;
 236
 237        /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
 238        regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
 239                (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
 240                (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
 241                (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
 242        /* Check for invalid user address space control. */
 243        if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
 244                regs->psw.mask = PSW_ASC_PRIMARY |
 245                        (regs->psw.mask & ~PSW_MASK_ASC);
 246        regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN);
 247        for (i = 0; i < NUM_GPRS; i++)
 248                regs->gprs[i] = (__u64) user_sregs.regs.gprs[i];
 249        memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
 250               sizeof(current->thread.acrs));
 251
 252        memcpy(&current->thread.fp_regs, &user_sregs.fpregs,
 253               sizeof(current->thread.fp_regs));
 254
 255        clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */
 256        return 0;
 257}
 258
 259static int save_sigregs_ext32(struct pt_regs *regs,
 260                              _sigregs_ext32 __user *sregs_ext)
 261{
 262        __u32 gprs_high[NUM_GPRS];
 263        __u64 vxrs[__NUM_VXRS_LOW];
 264        int i;
 265
 266        /* Save high gprs to signal stack */
 267        for (i = 0; i < NUM_GPRS; i++)
 268                gprs_high[i] = regs->gprs[i] >> 32;
 269        if (__copy_to_user(&sregs_ext->gprs_high, &gprs_high,
 270                           sizeof(sregs_ext->gprs_high)))
 271                return -EFAULT;
 272
 273        /* Save vector registers to signal stack */
 274        if (current->thread.vxrs) {
 275                for (i = 0; i < __NUM_VXRS_LOW; i++)
 276                        vxrs[i] = *((__u64 *)(current->thread.vxrs + i) + 1);
 277                if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
 278                                   sizeof(sregs_ext->vxrs_low)) ||
 279                    __copy_to_user(&sregs_ext->vxrs_high,
 280                                   current->thread.vxrs + __NUM_VXRS_LOW,
 281                                   sizeof(sregs_ext->vxrs_high)))
 282                        return -EFAULT;
 283        }
 284        return 0;
 285}
 286
 287static int restore_sigregs_ext32(struct pt_regs *regs,
 288                                 _sigregs_ext32 __user *sregs_ext)
 289{
 290        __u32 gprs_high[NUM_GPRS];
 291        __u64 vxrs[__NUM_VXRS_LOW];
 292        int i;
 293
 294        /* Restore high gprs from signal stack */
 295        if (__copy_from_user(&gprs_high, &sregs_ext->gprs_high,
 296                             sizeof(sregs_ext->gprs_high)))
 297                return -EFAULT;
 298        for (i = 0; i < NUM_GPRS; i++)
 299                *(__u32 *)&regs->gprs[i] = gprs_high[i];
 300
 301        /* Restore vector registers from signal stack */
 302        if (current->thread.vxrs) {
 303                if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
 304                                     sizeof(sregs_ext->vxrs_low)) ||
 305                    __copy_from_user(current->thread.vxrs + __NUM_VXRS_LOW,
 306                                     &sregs_ext->vxrs_high,
 307                                     sizeof(sregs_ext->vxrs_high)))
 308                        return -EFAULT;
 309                for (i = 0; i < __NUM_VXRS_LOW; i++)
 310                        *((__u64 *)(current->thread.vxrs + i) + 1) = vxrs[i];
 311        }
 312        return 0;
 313}
 314
 315asmlinkage long sys32_sigreturn(void)
 316{
 317        struct pt_regs *regs = task_pt_regs(current);
 318        sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
 319        compat_sigset_t cset;
 320        sigset_t set;
 321
 322        if (__copy_from_user(&cset.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
 323                goto badframe;
 324        sigset32_to_sigset(cset.sig, set.sig);
 325        set_current_blocked(&set);
 326        if (restore_sigregs32(regs, &frame->sregs))
 327                goto badframe;
 328        if (restore_sigregs_ext32(regs, &frame->sregs_ext))
 329                goto badframe;
 330        load_sigregs();
 331        return regs->gprs[2];
 332badframe:
 333        force_sig(SIGSEGV, current);
 334        return 0;
 335}
 336
 337asmlinkage long sys32_rt_sigreturn(void)
 338{
 339        struct pt_regs *regs = task_pt_regs(current);
 340        rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
 341        compat_sigset_t cset;
 342        sigset_t set;
 343
 344        if (__copy_from_user(&cset, &frame->uc.uc_sigmask, sizeof(cset)))
 345                goto badframe;
 346        sigset32_to_sigset(cset.sig, set.sig);
 347        set_current_blocked(&set);
 348        if (compat_restore_altstack(&frame->uc.uc_stack))
 349                goto badframe;
 350        if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
 351                goto badframe;
 352        if (restore_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
 353                goto badframe;
 354        load_sigregs();
 355        return regs->gprs[2];
 356badframe:
 357        force_sig(SIGSEGV, current);
 358        return 0;
 359}       
 360
 361/*
 362 * Set up a signal frame.
 363 */
 364
 365
 366/*
 367 * Determine which stack to use..
 368 */
 369static inline void __user *
 370get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
 371{
 372        unsigned long sp;
 373
 374        /* Default to using normal stack */
 375        sp = (unsigned long) A(regs->gprs[15]);
 376
 377        /* Overflow on alternate signal stack gives SIGSEGV. */
 378        if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
 379                return (void __user *) -1UL;
 380
 381        /* This is the X/Open sanctioned signal stack switching.  */
 382        if (ka->sa.sa_flags & SA_ONSTACK) {
 383                if (! sas_ss_flags(sp))
 384                        sp = current->sas_ss_sp + current->sas_ss_size;
 385        }
 386
 387        return (void __user *)((sp - frame_size) & -8ul);
 388}
 389
 390static inline int map_signal(int sig)
 391{
 392        if (current_thread_info()->exec_domain
 393            && current_thread_info()->exec_domain->signal_invmap
 394            && sig < 32)
 395                return current_thread_info()->exec_domain->signal_invmap[sig];
 396        else
 397                return sig;
 398}
 399
 400static int setup_frame32(int sig, struct k_sigaction *ka,
 401                        sigset_t *set, struct pt_regs * regs)
 402{
 403        sigframe32 __user *frame;
 404        struct sigcontext32 sc;
 405        unsigned long restorer;
 406        size_t frame_size;
 407
 408        /*
 409         * gprs_high are always present for 31-bit compat tasks.
 410         * The space for vector registers is only allocated if
 411         * the machine supports it
 412         */
 413        frame_size = sizeof(*frame) - sizeof(frame->sregs_ext.__reserved);
 414        if (!MACHINE_HAS_VX)
 415                frame_size -= sizeof(frame->sregs_ext.vxrs_low) +
 416                              sizeof(frame->sregs_ext.vxrs_high);
 417        frame = get_sigframe(ka, regs, frame_size);
 418        if (frame == (void __user *) -1UL)
 419                goto give_sigsegv;
 420
 421        /* Set up backchain. */
 422        if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
 423                goto give_sigsegv;
 424
 425        /* Create struct sigcontext32 on the signal stack */
 426        sigset_to_sigset32(set->sig, sc.oldmask);
 427        sc.sregs = (__u32)(unsigned long __force) &frame->sregs;
 428        if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
 429                goto give_sigsegv;
 430
 431        /* Store registers needed to create the signal frame */
 432        store_sigregs();
 433
 434        /* Create _sigregs32 on the signal stack */
 435        if (save_sigregs32(regs, &frame->sregs))
 436                goto give_sigsegv;
 437
 438        /* Place signal number on stack to allow backtrace from handler.  */
 439        if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
 440                goto give_sigsegv;
 441
 442        /* Create _sigregs_ext32 on the signal stack */
 443        if (save_sigregs_ext32(regs, &frame->sregs_ext))
 444                goto give_sigsegv;
 445
 446        /* Set up to return from userspace.  If provided, use a stub
 447           already in userspace.  */
 448        if (ka->sa.sa_flags & SA_RESTORER) {
 449                restorer = (unsigned long __force)
 450                        ka->sa.sa_restorer | PSW32_ADDR_AMODE;
 451        } else {
 452                /* Signal frames without vectors registers are short ! */
 453                __u16 __user *svc = (void *) frame + frame_size - 2;
 454                if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
 455                        goto give_sigsegv;
 456                restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
 457        }
 458
 459
 460        /* Set up registers for signal handler */
 461        regs->gprs[14] = restorer;
 462        regs->gprs[15] = (__force __u64) frame;
 463        /* Force 31 bit amode and default user address space control. */
 464        regs->psw.mask = PSW_MASK_BA |
 465                (PSW_USER_BITS & PSW_MASK_ASC) |
 466                (regs->psw.mask & ~PSW_MASK_ASC);
 467        regs->psw.addr = (__force __u64) ka->sa.sa_handler;
 468
 469        regs->gprs[2] = map_signal(sig);
 470        regs->gprs[3] = (__force __u64) &frame->sc;
 471
 472        /* We forgot to include these in the sigcontext.
 473           To avoid breaking binary compatibility, they are passed as args. */
 474        if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
 475            sig == SIGTRAP || sig == SIGFPE) {
 476                /* set extra registers only for synchronous signals */
 477                regs->gprs[4] = regs->int_code & 127;
 478                regs->gprs[5] = regs->int_parm_long;
 479                regs->gprs[6] = task_thread_info(current)->last_break;
 480        }
 481
 482        return 0;
 483
 484give_sigsegv:
 485        force_sigsegv(sig, current);
 486        return -EFAULT;
 487}
 488
 489static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
 490                           sigset_t *set, struct pt_regs * regs)
 491{
 492        compat_sigset_t cset;
 493        rt_sigframe32 __user *frame;
 494        unsigned long restorer;
 495        size_t frame_size;
 496        u32 uc_flags;
 497
 498        frame_size = sizeof(*frame) -
 499                     sizeof(frame->uc.uc_mcontext_ext.__reserved);
 500        /*
 501         * gprs_high are always present for 31-bit compat tasks.
 502         * The space for vector registers is only allocated if
 503         * the machine supports it
 504         */
 505        uc_flags = UC_GPRS_HIGH;
 506        if (MACHINE_HAS_VX) {
 507                if (current->thread.vxrs)
 508                        uc_flags |= UC_VXRS;
 509        } else
 510                frame_size -= sizeof(frame->uc.uc_mcontext_ext.vxrs_low) +
 511                              sizeof(frame->uc.uc_mcontext_ext.vxrs_high);
 512        frame = get_sigframe(ka, regs, frame_size);
 513        if (frame == (void __user *) -1UL)
 514                goto give_sigsegv;
 515
 516        /* Set up backchain. */
 517        if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
 518                goto give_sigsegv;
 519
 520        /* Set up to return from userspace.  If provided, use a stub
 521           already in userspace.  */
 522        if (ka->sa.sa_flags & SA_RESTORER) {
 523                restorer = (unsigned long __force)
 524                        ka->sa.sa_restorer | PSW32_ADDR_AMODE;
 525        } else {
 526                __u16 __user *svc = &frame->svc_insn;
 527                if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))
 528                        goto give_sigsegv;
 529                restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
 530        }
 531
 532        /* Create siginfo on the signal stack */
 533        if (copy_siginfo_to_user32(&frame->info, info))
 534                goto give_sigsegv;
 535
 536        /* Store registers needed to create the signal frame */
 537        store_sigregs();
 538
 539        /* Create ucontext on the signal stack. */
 540        sigset_to_sigset32(set->sig, cset.sig);
 541        if (__put_user(uc_flags, &frame->uc.uc_flags) ||
 542            __put_user(0, &frame->uc.uc_link) ||
 543            __compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
 544            save_sigregs32(regs, &frame->uc.uc_mcontext) ||
 545            __copy_to_user(&frame->uc.uc_sigmask, &cset, sizeof(cset)) ||
 546            save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
 547                goto give_sigsegv;
 548
 549        /* Set up registers for signal handler */
 550        regs->gprs[14] = restorer;
 551        regs->gprs[15] = (__force __u64) frame;
 552        /* Force 31 bit amode and default user address space control. */
 553        regs->psw.mask = PSW_MASK_BA |
 554                (PSW_USER_BITS & PSW_MASK_ASC) |
 555                (regs->psw.mask & ~PSW_MASK_ASC);
 556        regs->psw.addr = (__u64) ka->sa.sa_handler;
 557
 558        regs->gprs[2] = map_signal(sig);
 559        regs->gprs[3] = (__force __u64) &frame->info;
 560        regs->gprs[4] = (__force __u64) &frame->uc;
 561        regs->gprs[5] = task_thread_info(current)->last_break;
 562        return 0;
 563
 564give_sigsegv:
 565        force_sigsegv(sig, current);
 566        return -EFAULT;
 567}
 568
 569/*
 570 * OK, we're invoking a handler
 571 */     
 572
 573void handle_signal32(unsigned long sig, struct k_sigaction *ka,
 574                    siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 575{
 576        int ret;
 577
 578        /* Set up the stack frame */
 579        if (ka->sa.sa_flags & SA_SIGINFO)
 580                ret = setup_rt_frame32(sig, ka, info, oldset, regs);
 581        else
 582                ret = setup_frame32(sig, ka, oldset, regs);
 583        if (ret)
 584                return;
 585        signal_delivered(sig, info, ka, regs,
 586                                 test_thread_flag(TIF_SINGLE_STEP));
 587}
 588
 589