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