linux/arch/ia64/ia32/ia32_signal.c
<<
>>
Prefs
   1/*
   2 * IA32 Architecture-specific signal handling support.
   3 *
   4 * Copyright (C) 1999, 2001-2002, 2005 Hewlett-Packard Co
   5 *      David Mosberger-Tang <davidm@hpl.hp.com>
   6 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
   7 * Copyright (C) 2000 VA Linux Co
   8 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
   9 *
  10 * Derived from i386 and Alpha versions.
  11 */
  12
  13#include <linux/errno.h>
  14#include <linux/kernel.h>
  15#include <linux/mm.h>
  16#include <linux/personality.h>
  17#include <linux/ptrace.h>
  18#include <linux/sched.h>
  19#include <linux/signal.h>
  20#include <linux/smp.h>
  21#include <linux/stddef.h>
  22#include <linux/syscalls.h>
  23#include <linux/unistd.h>
  24#include <linux/wait.h>
  25#include <linux/compat.h>
  26
  27#include <asm/intrinsics.h>
  28#include <asm/uaccess.h>
  29#include <asm/rse.h>
  30#include <asm/sigcontext.h>
  31
  32#include "ia32priv.h"
  33
  34#include "../kernel/sigframe.h"
  35
  36#define A(__x)          ((unsigned long)(__x))
  37
  38#define DEBUG_SIG       0
  39#define _BLOCKABLE      (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  40
  41#define __IA32_NR_sigreturn            119
  42#define __IA32_NR_rt_sigreturn         173
  43
  44struct sigframe_ia32
  45{
  46       int pretcode;
  47       int sig;
  48       struct sigcontext_ia32 sc;
  49       struct _fpstate_ia32 fpstate;
  50       unsigned int extramask[_COMPAT_NSIG_WORDS-1];
  51       char retcode[8];
  52};
  53
  54struct rt_sigframe_ia32
  55{
  56       int pretcode;
  57       int sig;
  58       int pinfo;
  59       int puc;
  60       compat_siginfo_t info;
  61       struct ucontext_ia32 uc;
  62       struct _fpstate_ia32 fpstate;
  63       char retcode[8];
  64};
  65
  66int
  67copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
  68{
  69        unsigned long tmp;
  70        int err;
  71
  72        if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
  73                return -EFAULT;
  74
  75        err = __get_user(to->si_signo, &from->si_signo);
  76        err |= __get_user(to->si_errno, &from->si_errno);
  77        err |= __get_user(to->si_code, &from->si_code);
  78
  79        if (to->si_code < 0)
  80                err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
  81        else {
  82                switch (to->si_code >> 16) {
  83                      case __SI_CHLD >> 16:
  84                        err |= __get_user(to->si_utime, &from->si_utime);
  85                        err |= __get_user(to->si_stime, &from->si_stime);
  86                        err |= __get_user(to->si_status, &from->si_status);
  87                      default:
  88                        err |= __get_user(to->si_pid, &from->si_pid);
  89                        err |= __get_user(to->si_uid, &from->si_uid);
  90                        break;
  91                      case __SI_FAULT >> 16:
  92                        err |= __get_user(tmp, &from->si_addr);
  93                        to->si_addr = (void __user *) tmp;
  94                        break;
  95                      case __SI_POLL >> 16:
  96                        err |= __get_user(to->si_band, &from->si_band);
  97                        err |= __get_user(to->si_fd, &from->si_fd);
  98                        break;
  99                      case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 100                      case __SI_MESGQ >> 16:
 101                        err |= __get_user(to->si_pid, &from->si_pid);
 102                        err |= __get_user(to->si_uid, &from->si_uid);
 103                        err |= __get_user(to->si_int, &from->si_int);
 104                        break;
 105                }
 106        }
 107        return err;
 108}
 109
 110int
 111copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
 112{
 113        unsigned int addr;
 114        int err;
 115
 116        if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 117                return -EFAULT;
 118
 119        /* If you change siginfo_t structure, please be sure
 120           this code is fixed accordingly.
 121           It should never copy any pad contained in the structure
 122           to avoid security leaks, but must copy the generic
 123           3 ints plus the relevant union member.
 124           This routine must convert siginfo from 64bit to 32bit as well
 125           at the same time.  */
 126        err = __put_user(from->si_signo, &to->si_signo);
 127        err |= __put_user(from->si_errno, &to->si_errno);
 128        err |= __put_user((short)from->si_code, &to->si_code);
 129        if (from->si_code < 0)
 130                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 131        else {
 132                switch (from->si_code >> 16) {
 133                case __SI_CHLD >> 16:
 134                        err |= __put_user(from->si_utime, &to->si_utime);
 135                        err |= __put_user(from->si_stime, &to->si_stime);
 136                        err |= __put_user(from->si_status, &to->si_status);
 137                default:
 138                        err |= __put_user(from->si_pid, &to->si_pid);
 139                        err |= __put_user(from->si_uid, &to->si_uid);
 140                        break;
 141                case __SI_FAULT >> 16:
 142                        /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */
 143                        err |= __put_user(from->_sifields._pad[0], &to->si_addr);
 144                        break;
 145                case __SI_POLL >> 16:
 146                        err |= __put_user(from->si_band, &to->si_band);
 147                        err |= __put_user(from->si_fd, &to->si_fd);
 148                        break;
 149                case __SI_TIMER >> 16:
 150                        err |= __put_user(from->si_tid, &to->si_tid);
 151                        err |= __put_user(from->si_overrun, &to->si_overrun);
 152                        addr = (unsigned long) from->si_ptr;
 153                        err |= __put_user(addr, &to->si_ptr);
 154                        break;
 155                case __SI_RT >> 16:     /* Not generated by the kernel as of now.  */
 156                case __SI_MESGQ >> 16:
 157                        err |= __put_user(from->si_uid, &to->si_uid);
 158                        err |= __put_user(from->si_pid, &to->si_pid);
 159                        addr = (unsigned long) from->si_ptr;
 160                        err |= __put_user(addr, &to->si_ptr);
 161                        break;
 162                }
 163        }
 164        return err;
 165}
 166
 167
 168/*
 169 *  SAVE and RESTORE of ia32 fpstate info, from ia64 current state
 170 *  Used in exception handler to pass the fpstate to the user, and restore
 171 *  the fpstate while returning from the exception handler.
 172 *
 173 *    fpstate info and their mapping to IA64 regs:
 174 *    fpstate    REG(BITS)      Attribute    Comments
 175 *    cw         ar.fcr(0:12)                with bits 7 and 6 not used
 176 *    sw         ar.fsr(0:15)
 177 *    tag        ar.fsr(16:31)               with odd numbered bits not used
 178 *                                           (read returns 0, writes ignored)
 179 *    ipoff      ar.fir(0:31)
 180 *    cssel      ar.fir(32:47)
 181 *    dataoff    ar.fdr(0:31)
 182 *    datasel    ar.fdr(32:47)
 183 *
 184 *    _st[(0+TOS)%8]   f8
 185 *    _st[(1+TOS)%8]   f9
 186 *    _st[(2+TOS)%8]   f10
 187 *    _st[(3+TOS)%8]   f11                   (f8..f11 from ptregs)
 188 *      : :            :                     (f12..f15 from live reg)
 189 *      : :            :
 190 *    _st[(7+TOS)%8]   f15                   TOS=sw.top(bits11:13)
 191 *
 192 *    status     Same as sw     RO
 193 *    magic      0                           as X86_FXSR_MAGIC in ia32
 194 *    mxcsr      Bits(7:15)=ar.fcr(39:47)
 195 *               Bits(0:5) =ar.fsr(32:37)    with bit 6 reserved
 196 *    _xmm[0..7] f16..f31                    (live registers)
 197 *                                           with _xmm[0]
 198 *                                             Bit(64:127)=f17(0:63)
 199 *                                             Bit(0:63)=f16(0:63)
 200 *    All other fields unused...
 201 */
 202
 203static int
 204save_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
 205{
 206        struct task_struct *tsk = current;
 207        struct pt_regs *ptp;
 208        struct _fpreg_ia32 *fpregp;
 209        char buf[32];
 210        unsigned long fsr, fcr, fir, fdr;
 211        unsigned long new_fsr;
 212        unsigned long num128[2];
 213        unsigned long mxcsr=0;
 214        int fp_tos, fr8_st_map;
 215
 216        if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
 217                return -EFAULT;
 218
 219        /* Read in fsr, fcr, fir, fdr and copy onto fpstate */
 220        fsr = ia64_getreg(_IA64_REG_AR_FSR);
 221        fcr = ia64_getreg(_IA64_REG_AR_FCR);
 222        fir = ia64_getreg(_IA64_REG_AR_FIR);
 223        fdr = ia64_getreg(_IA64_REG_AR_FDR);
 224
 225        /*
 226         * We need to clear the exception state before calling the signal handler. Clear
 227         * the bits 15, bits 0-7 in fp status word. Similar to the functionality of fnclex
 228         * instruction.
 229         */
 230        new_fsr = fsr & ~0x80ff;
 231        ia64_setreg(_IA64_REG_AR_FSR, new_fsr);
 232
 233        __put_user(fcr & 0xffff, &save->cw);
 234        __put_user(fsr & 0xffff, &save->sw);
 235        __put_user((fsr>>16) & 0xffff, &save->tag);
 236        __put_user(fir, &save->ipoff);
 237        __put_user((fir>>32) & 0xffff, &save->cssel);
 238        __put_user(fdr, &save->dataoff);
 239        __put_user((fdr>>32) & 0xffff, &save->datasel);
 240        __put_user(fsr & 0xffff, &save->status);
 241
 242        mxcsr = ((fcr>>32) & 0xff80) | ((fsr>>32) & 0x3f);
 243        __put_user(mxcsr & 0xffff, &save->mxcsr);
 244        __put_user( 0, &save->magic); //#define X86_FXSR_MAGIC   0x0000
 245
 246        /*
 247         * save f8..f11  from pt_regs
 248         * save f12..f15 from live register set
 249         */
 250        /*
 251         *  Find the location where f8 has to go in fp reg stack.  This depends on
 252         *  TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps
 253         *  to.
 254         */
 255        fp_tos = (fsr>>11)&0x7;
 256        fr8_st_map = (8-fp_tos)&0x7;
 257        ptp = task_pt_regs(tsk);
 258        fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
 259        ia64f2ia32f(fpregp, &ptp->f8);
 260        copy_to_user(&save->_st[(0+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 261        ia64f2ia32f(fpregp, &ptp->f9);
 262        copy_to_user(&save->_st[(1+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 263        ia64f2ia32f(fpregp, &ptp->f10);
 264        copy_to_user(&save->_st[(2+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 265        ia64f2ia32f(fpregp, &ptp->f11);
 266        copy_to_user(&save->_st[(3+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 267
 268        ia64_stfe(fpregp, 12);
 269        copy_to_user(&save->_st[(4+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 270        ia64_stfe(fpregp, 13);
 271        copy_to_user(&save->_st[(5+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 272        ia64_stfe(fpregp, 14);
 273        copy_to_user(&save->_st[(6+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 274        ia64_stfe(fpregp, 15);
 275        copy_to_user(&save->_st[(7+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 276
 277        ia64_stf8(&num128[0], 16);
 278        ia64_stf8(&num128[1], 17);
 279        copy_to_user(&save->_xmm[0], num128, sizeof(struct _xmmreg_ia32));
 280
 281        ia64_stf8(&num128[0], 18);
 282        ia64_stf8(&num128[1], 19);
 283        copy_to_user(&save->_xmm[1], num128, sizeof(struct _xmmreg_ia32));
 284
 285        ia64_stf8(&num128[0], 20);
 286        ia64_stf8(&num128[1], 21);
 287        copy_to_user(&save->_xmm[2], num128, sizeof(struct _xmmreg_ia32));
 288
 289        ia64_stf8(&num128[0], 22);
 290        ia64_stf8(&num128[1], 23);
 291        copy_to_user(&save->_xmm[3], num128, sizeof(struct _xmmreg_ia32));
 292
 293        ia64_stf8(&num128[0], 24);
 294        ia64_stf8(&num128[1], 25);
 295        copy_to_user(&save->_xmm[4], num128, sizeof(struct _xmmreg_ia32));
 296
 297        ia64_stf8(&num128[0], 26);
 298        ia64_stf8(&num128[1], 27);
 299        copy_to_user(&save->_xmm[5], num128, sizeof(struct _xmmreg_ia32));
 300
 301        ia64_stf8(&num128[0], 28);
 302        ia64_stf8(&num128[1], 29);
 303        copy_to_user(&save->_xmm[6], num128, sizeof(struct _xmmreg_ia32));
 304
 305        ia64_stf8(&num128[0], 30);
 306        ia64_stf8(&num128[1], 31);
 307        copy_to_user(&save->_xmm[7], num128, sizeof(struct _xmmreg_ia32));
 308        return 0;
 309}
 310
 311static int
 312restore_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
 313{
 314        struct task_struct *tsk = current;
 315        struct pt_regs *ptp;
 316        unsigned int lo, hi;
 317        unsigned long num128[2];
 318        unsigned long num64, mxcsr;
 319        struct _fpreg_ia32 *fpregp;
 320        char buf[32];
 321        unsigned long fsr, fcr, fir, fdr;
 322        int fp_tos, fr8_st_map;
 323
 324        if (!access_ok(VERIFY_READ, save, sizeof(*save)))
 325                return(-EFAULT);
 326
 327        /*
 328         * Updating fsr, fcr, fir, fdr.
 329         * Just a bit more complicated than save.
 330         * - Need to make sure that we don't write any value other than the
 331         *   specific fpstate info
 332         * - Need to make sure that the untouched part of frs, fdr, fir, fcr
 333         *   should remain same while writing.
 334         * So, we do a read, change specific fields and write.
 335         */
 336        fsr = ia64_getreg(_IA64_REG_AR_FSR);
 337        fcr = ia64_getreg(_IA64_REG_AR_FCR);
 338        fir = ia64_getreg(_IA64_REG_AR_FIR);
 339        fdr = ia64_getreg(_IA64_REG_AR_FDR);
 340
 341        __get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
 342        /* setting bits 0..5 8..12 with cw and 39..47 from mxcsr */
 343        __get_user(lo, (unsigned int __user *)&save->cw);
 344        num64 = mxcsr & 0xff10;
 345        num64 = (num64 << 32) | (lo & 0x1f3f);
 346        fcr = (fcr & (~0xff1000001f3fUL)) | num64;
 347
 348        /* setting bits 0..31 with sw and tag and 32..37 from mxcsr */
 349        __get_user(lo, (unsigned int __user *)&save->sw);
 350        /* set bits 15,7 (fsw.b, fsw.es) to reflect the current error status */
 351        if ( !(lo & 0x7f) )
 352                lo &= (~0x8080);
 353        __get_user(hi, (unsigned int __user *)&save->tag);
 354        num64 = mxcsr & 0x3f;
 355        num64 = (num64 << 16) | (hi & 0xffff);
 356        num64 = (num64 << 16) | (lo & 0xffff);
 357        fsr = (fsr & (~0x3fffffffffUL)) | num64;
 358
 359        /* setting bits 0..47 with cssel and ipoff */
 360        __get_user(lo, (unsigned int __user *)&save->ipoff);
 361        __get_user(hi, (unsigned int __user *)&save->cssel);
 362        num64 = hi & 0xffff;
 363        num64 = (num64 << 32) | lo;
 364        fir = (fir & (~0xffffffffffffUL)) | num64;
 365
 366        /* setting bits 0..47 with datasel and dataoff */
 367        __get_user(lo, (unsigned int __user *)&save->dataoff);
 368        __get_user(hi, (unsigned int __user *)&save->datasel);
 369        num64 = hi & 0xffff;
 370        num64 = (num64 << 32) | lo;
 371        fdr = (fdr & (~0xffffffffffffUL)) | num64;
 372
 373        ia64_setreg(_IA64_REG_AR_FSR, fsr);
 374        ia64_setreg(_IA64_REG_AR_FCR, fcr);
 375        ia64_setreg(_IA64_REG_AR_FIR, fir);
 376        ia64_setreg(_IA64_REG_AR_FDR, fdr);
 377
 378        /*
 379         * restore f8..f11 onto pt_regs
 380         * restore f12..f15 onto live registers
 381         */
 382        /*
 383         *  Find the location where f8 has to go in fp reg stack.  This depends on
 384         *  TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps
 385         *  to.
 386         */
 387        fp_tos = (fsr>>11)&0x7;
 388        fr8_st_map = (8-fp_tos)&0x7;
 389        fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
 390
 391        ptp = task_pt_regs(tsk);
 392        copy_from_user(fpregp, &save->_st[(0+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 393        ia32f2ia64f(&ptp->f8, fpregp);
 394        copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 395        ia32f2ia64f(&ptp->f9, fpregp);
 396        copy_from_user(fpregp, &save->_st[(2+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 397        ia32f2ia64f(&ptp->f10, fpregp);
 398        copy_from_user(fpregp, &save->_st[(3+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 399        ia32f2ia64f(&ptp->f11, fpregp);
 400
 401        copy_from_user(fpregp, &save->_st[(4+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 402        ia64_ldfe(12, fpregp);
 403        copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 404        ia64_ldfe(13, fpregp);
 405        copy_from_user(fpregp, &save->_st[(6+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 406        ia64_ldfe(14, fpregp);
 407        copy_from_user(fpregp, &save->_st[(7+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 408        ia64_ldfe(15, fpregp);
 409
 410        copy_from_user(num128, &save->_xmm[0], sizeof(struct _xmmreg_ia32));
 411        ia64_ldf8(16, &num128[0]);
 412        ia64_ldf8(17, &num128[1]);
 413
 414        copy_from_user(num128, &save->_xmm[1], sizeof(struct _xmmreg_ia32));
 415        ia64_ldf8(18, &num128[0]);
 416        ia64_ldf8(19, &num128[1]);
 417
 418        copy_from_user(num128, &save->_xmm[2], sizeof(struct _xmmreg_ia32));
 419        ia64_ldf8(20, &num128[0]);
 420        ia64_ldf8(21, &num128[1]);
 421
 422        copy_from_user(num128, &save->_xmm[3], sizeof(struct _xmmreg_ia32));
 423        ia64_ldf8(22, &num128[0]);
 424        ia64_ldf8(23, &num128[1]);
 425
 426        copy_from_user(num128, &save->_xmm[4], sizeof(struct _xmmreg_ia32));
 427        ia64_ldf8(24, &num128[0]);
 428        ia64_ldf8(25, &num128[1]);
 429
 430        copy_from_user(num128, &save->_xmm[5], sizeof(struct _xmmreg_ia32));
 431        ia64_ldf8(26, &num128[0]);
 432        ia64_ldf8(27, &num128[1]);
 433
 434        copy_from_user(num128, &save->_xmm[6], sizeof(struct _xmmreg_ia32));
 435        ia64_ldf8(28, &num128[0]);
 436        ia64_ldf8(29, &num128[1]);
 437
 438        copy_from_user(num128, &save->_xmm[7], sizeof(struct _xmmreg_ia32));
 439        ia64_ldf8(30, &num128[0]);
 440        ia64_ldf8(31, &num128[1]);
 441        return 0;
 442}
 443
 444static inline void
 445sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int restorer)
 446{
 447        if (handler + 1 <= 2)
 448                /* SIG_DFL, SIG_IGN, or SIG_ERR: must sign-extend to 64-bits */
 449                sa->sa.sa_handler = (__sighandler_t) A((int) handler);
 450        else
 451                sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler);
 452}
 453
 454asmlinkage long
 455sys32_sigsuspend (int history0, int history1, old_sigset_t mask)
 456{
 457        mask &= _BLOCKABLE;
 458        spin_lock_irq(&current->sighand->siglock);
 459        current->saved_sigmask = current->blocked;
 460        siginitset(&current->blocked, mask);
 461        recalc_sigpending();
 462        spin_unlock_irq(&current->sighand->siglock);
 463
 464        current->state = TASK_INTERRUPTIBLE;
 465        schedule();
 466        set_restore_sigmask();
 467        return -ERESTARTNOHAND;
 468}
 469
 470asmlinkage long
 471sys32_signal (int sig, unsigned int handler)
 472{
 473        struct k_sigaction new_sa, old_sa;
 474        int ret;
 475
 476        sigact_set_handler(&new_sa, handler, 0);
 477        new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
 478        sigemptyset(&new_sa.sa.sa_mask);
 479
 480        ret = do_sigaction(sig, &new_sa, &old_sa);
 481
 482        return ret ? ret : IA32_SA_HANDLER(&old_sa);
 483}
 484
 485asmlinkage long
 486sys32_rt_sigaction (int sig, struct sigaction32 __user *act,
 487                    struct sigaction32 __user *oact, unsigned int sigsetsize)
 488{
 489        struct k_sigaction new_ka, old_ka;
 490        unsigned int handler, restorer;
 491        int ret;
 492
 493        /* XXX: Don't preclude handling different sized sigset_t's.  */
 494        if (sigsetsize != sizeof(compat_sigset_t))
 495                return -EINVAL;
 496
 497        if (act) {
 498                ret = get_user(handler, &act->sa_handler);
 499                ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
 500                ret |= get_user(restorer, &act->sa_restorer);
 501                ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(compat_sigset_t));
 502                if (ret)
 503                        return -EFAULT;
 504
 505                sigact_set_handler(&new_ka, handler, restorer);
 506        }
 507
 508        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 509
 510        if (!ret && oact) {
 511                ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
 512                ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 513                ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
 514                ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(compat_sigset_t));
 515        }
 516        return ret;
 517}
 518
 519
 520asmlinkage long
 521sys32_rt_sigprocmask (int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
 522                      unsigned int sigsetsize)
 523{
 524        mm_segment_t old_fs = get_fs();
 525        sigset_t s;
 526        long ret;
 527
 528        if (sigsetsize > sizeof(s))
 529                return -EINVAL;
 530
 531        if (set) {
 532                memset(&s, 0, sizeof(s));
 533                if (copy_from_user(&s.sig, set, sigsetsize))
 534                        return -EFAULT;
 535        }
 536        set_fs(KERNEL_DS);
 537        ret = sys_rt_sigprocmask(how,
 538                                 set ? (sigset_t __user *) &s : NULL,
 539                                 oset ? (sigset_t __user *) &s : NULL, sizeof(s));
 540        set_fs(old_fs);
 541        if (ret)
 542                return ret;
 543        if (oset) {
 544                if (copy_to_user(oset, &s.sig, sigsetsize))
 545                        return -EFAULT;
 546        }
 547        return 0;
 548}
 549
 550asmlinkage long
 551sys32_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo)
 552{
 553        mm_segment_t old_fs = get_fs();
 554        siginfo_t info;
 555        int ret;
 556
 557        if (copy_siginfo_from_user32(&info, uinfo))
 558                return -EFAULT;
 559        set_fs(KERNEL_DS);
 560        ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
 561        set_fs(old_fs);
 562        return ret;
 563}
 564
 565asmlinkage long
 566sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
 567{
 568        struct k_sigaction new_ka, old_ka;
 569        unsigned int handler, restorer;
 570        int ret;
 571
 572        if (act) {
 573                compat_old_sigset_t mask;
 574
 575                ret = get_user(handler, &act->sa_handler);
 576                ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
 577                ret |= get_user(restorer, &act->sa_restorer);
 578                ret |= get_user(mask, &act->sa_mask);
 579                if (ret)
 580                        return ret;
 581
 582                sigact_set_handler(&new_ka, handler, restorer);
 583                siginitset(&new_ka.sa.sa_mask, mask);
 584        }
 585
 586        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 587
 588        if (!ret && oact) {
 589                ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
 590                ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 591                ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
 592                ret |= put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
 593        }
 594
 595        return ret;
 596}
 597
 598static int
 599setup_sigcontext_ia32 (struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
 600                       struct pt_regs *regs, unsigned long mask)
 601{
 602        int  err = 0;
 603        unsigned long flag;
 604
 605        if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc)))
 606                return -EFAULT;
 607
 608        err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int __user *)&sc->fs);
 609        err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int __user *)&sc->gs);
 610        err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int __user *)&sc->es);
 611        err |= __put_user(regs->r16 & 0xffff, (unsigned int __user *)&sc->ds);
 612        err |= __put_user(regs->r15, &sc->edi);
 613        err |= __put_user(regs->r14, &sc->esi);
 614        err |= __put_user(regs->r13, &sc->ebp);
 615        err |= __put_user(regs->r12, &sc->esp);
 616        err |= __put_user(regs->r11, &sc->ebx);
 617        err |= __put_user(regs->r10, &sc->edx);
 618        err |= __put_user(regs->r9, &sc->ecx);
 619        err |= __put_user(regs->r8, &sc->eax);
 620#if 0
 621        err |= __put_user(current->tss.trap_no, &sc->trapno);
 622        err |= __put_user(current->tss.error_code, &sc->err);
 623#endif
 624        err |= __put_user(regs->cr_iip, &sc->eip);
 625        err |= __put_user(regs->r17 & 0xffff, (unsigned int __user *)&sc->cs);
 626        /*
 627         *  `eflags' is in an ar register for this context
 628         */
 629        flag = ia64_getreg(_IA64_REG_AR_EFLAG);
 630        err |= __put_user((unsigned int)flag, &sc->eflags);
 631        err |= __put_user(regs->r12, &sc->esp_at_signal);
 632        err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int __user *)&sc->ss);
 633
 634        if ( save_ia32_fpstate_live(fpstate) < 0 )
 635                err = -EFAULT;
 636        else
 637                err |= __put_user((u32)(u64)fpstate, &sc->fpstate);
 638
 639#if 0
 640        tmp = save_i387(fpstate);
 641        if (tmp < 0)
 642                err = 1;
 643        else
 644                err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
 645
 646        /* non-iBCS2 extensions.. */
 647#endif
 648        err |= __put_user(mask, &sc->oldmask);
 649#if 0
 650        err |= __put_user(current->tss.cr2, &sc->cr2);
 651#endif
 652        return err;
 653}
 654
 655static int
 656restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 __user *sc, int *peax)
 657{
 658        unsigned int err = 0;
 659
 660        /* Always make any pending restarted system calls return -EINTR */
 661        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 662
 663        if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
 664                return(-EFAULT);
 665
 666#define COPY(ia64x, ia32x)      err |= __get_user(regs->ia64x, &sc->ia32x)
 667
 668#define copyseg_gs(tmp)         (regs->r16 |= (unsigned long) (tmp) << 48)
 669#define copyseg_fs(tmp)         (regs->r16 |= (unsigned long) (tmp) << 32)
 670#define copyseg_cs(tmp)         (regs->r17 |= tmp)
 671#define copyseg_ss(tmp)         (regs->r17 |= (unsigned long) (tmp) << 16)
 672#define copyseg_es(tmp)         (regs->r16 |= (unsigned long) (tmp) << 16)
 673#define copyseg_ds(tmp)         (regs->r16 |= tmp)
 674
 675#define COPY_SEG(seg)                                   \
 676        {                                               \
 677                unsigned short tmp;                     \
 678                err |= __get_user(tmp, &sc->seg);       \
 679                copyseg_##seg(tmp);                     \
 680        }
 681#define COPY_SEG_STRICT(seg)                            \
 682        {                                               \
 683                unsigned short tmp;                     \
 684                err |= __get_user(tmp, &sc->seg);       \
 685                copyseg_##seg(tmp|3);                   \
 686        }
 687
 688        /* To make COPY_SEGs easier, we zero r16, r17 */
 689        regs->r16 = 0;
 690        regs->r17 = 0;
 691
 692        COPY_SEG(gs);
 693        COPY_SEG(fs);
 694        COPY_SEG(es);
 695        COPY_SEG(ds);
 696        COPY(r15, edi);
 697        COPY(r14, esi);
 698        COPY(r13, ebp);
 699        COPY(r12, esp);
 700        COPY(r11, ebx);
 701        COPY(r10, edx);
 702        COPY(r9, ecx);
 703        COPY(cr_iip, eip);
 704        COPY_SEG_STRICT(cs);
 705        COPY_SEG_STRICT(ss);
 706        ia32_load_segment_descriptors(current);
 707        {
 708                unsigned int tmpflags;
 709                unsigned long flag;
 710
 711                /*
 712                 *  IA32 `eflags' is not part of `pt_regs', it's in an ar register which
 713                 *  is part of the thread context.  Fortunately, we are executing in the
 714                 *  IA32 process's context.
 715                 */
 716                err |= __get_user(tmpflags, &sc->eflags);
 717                flag = ia64_getreg(_IA64_REG_AR_EFLAG);
 718                flag &= ~0x40DD5;
 719                flag |= (tmpflags & 0x40DD5);
 720                ia64_setreg(_IA64_REG_AR_EFLAG, flag);
 721
 722                regs->r1 = -1;  /* disable syscall checks, r1 is orig_eax */
 723        }
 724
 725        {
 726                struct _fpstate_ia32 __user *buf = NULL;
 727                u32    fpstate_ptr;
 728                err |= get_user(fpstate_ptr, &(sc->fpstate));
 729                buf = compat_ptr(fpstate_ptr);
 730                if (buf) {
 731                        err |= restore_ia32_fpstate_live(buf);
 732                }
 733        }
 734
 735#if 0
 736        {
 737                struct _fpstate * buf;
 738                err |= __get_user(buf, &sc->fpstate);
 739                if (buf) {
 740                        if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
 741                                goto badframe;
 742                        err |= restore_i387(buf);
 743                }
 744        }
 745#endif
 746
 747        err |= __get_user(*peax, &sc->eax);
 748        return err;
 749
 750#if 0
 751  badframe:
 752        return 1;
 753#endif
 754}
 755
 756/*
 757 * Determine which stack to use..
 758 */
 759static inline void __user *
 760get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
 761{
 762        unsigned long esp;
 763
 764        /* Default to using normal stack (truncate off sign-extension of bit 31: */
 765        esp = (unsigned int) regs->r12;
 766
 767        /* This is the X/Open sanctioned signal stack switching.  */
 768        if (ka->sa.sa_flags & SA_ONSTACK) {
 769                int onstack = sas_ss_flags(esp);
 770
 771                if (onstack == 0)
 772                        esp = current->sas_ss_sp + current->sas_ss_size;
 773                else if (onstack == SS_ONSTACK) {
 774                        /*
 775                         * If we are on the alternate signal stack and would
 776                         * overflow it, don't. Return an always-bogus address
 777                         * instead so we will die with SIGSEGV.
 778                         */
 779                        if (!likely(on_sig_stack(esp - frame_size)))
 780                                return (void __user *) -1L;
 781                }
 782        }
 783        /* Legacy stack switching not supported */
 784
 785        esp -= frame_size;
 786        /* Align the stack pointer according to the i386 ABI,
 787         * i.e. so that on function entry ((sp + 4) & 15) == 0. */
 788        esp = ((esp + 4) & -16ul) - 4;
 789        return (void __user *) esp;
 790}
 791
 792static int
 793setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
 794{
 795        struct exec_domain *ed = current_thread_info()->exec_domain;
 796        struct sigframe_ia32 __user *frame;
 797        int err = 0;
 798
 799        frame = get_sigframe(ka, regs, sizeof(*frame));
 800
 801        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 802                goto give_sigsegv;
 803
 804        err |= __put_user((ed && ed->signal_invmap && sig < 32
 805                           ? (int)(ed->signal_invmap[sig]) : sig), &frame->sig);
 806
 807        err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
 808
 809        if (_COMPAT_NSIG_WORDS > 1)
 810                err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4,
 811                                      sizeof(frame->extramask));
 812
 813        /* Set up to return from userspace.  If provided, use a stub
 814           already in userspace.  */
 815        if (ka->sa.sa_flags & SA_RESTORER) {
 816                unsigned int restorer = IA32_SA_RESTORER(ka);
 817                err |= __put_user(restorer, &frame->pretcode);
 818        } else {
 819                /* Pointing to restorer in ia32 gate page */
 820                err |= __put_user(IA32_GATE_OFFSET, &frame->pretcode);
 821        }
 822
 823        /* This is popl %eax ; movl $,%eax ; int $0x80
 824         * and there for historical reasons only.
 825         * See arch/i386/kernel/signal.c
 826         */
 827
 828        err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
 829        err |= __put_user(__IA32_NR_sigreturn, (int __user *)(frame->retcode+2));
 830        err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
 831
 832        if (err)
 833                goto give_sigsegv;
 834
 835        /* Set up registers for signal handler */
 836        regs->r12 = (unsigned long) frame;
 837        regs->cr_iip = IA32_SA_HANDLER(ka);
 838
 839        set_fs(USER_DS);
 840
 841#if 0
 842        regs->eflags &= ~TF_MASK;
 843#endif
 844
 845#if 0
 846        printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n",
 847               current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode);
 848#endif
 849
 850        return 1;
 851
 852  give_sigsegv:
 853        force_sigsegv(sig, current);
 854        return 0;
 855}
 856
 857static int
 858setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
 859                     sigset_t *set, struct pt_regs * regs)
 860{
 861        struct exec_domain *ed = current_thread_info()->exec_domain;
 862        compat_uptr_t pinfo, puc;
 863        struct rt_sigframe_ia32 __user *frame;
 864        int err = 0;
 865
 866        frame = get_sigframe(ka, regs, sizeof(*frame));
 867
 868        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 869                goto give_sigsegv;
 870
 871        err |= __put_user((ed && ed->signal_invmap
 872                           && sig < 32 ? ed->signal_invmap[sig] : sig), &frame->sig);
 873
 874        pinfo = (long __user) &frame->info;
 875        puc = (long __user) &frame->uc;
 876        err |= __put_user(pinfo, &frame->pinfo);
 877        err |= __put_user(puc, &frame->puc);
 878        err |= copy_siginfo_to_user32(&frame->info, info);
 879
 880        /* Create the ucontext.  */
 881        err |= __put_user(0, &frame->uc.uc_flags);
 882        err |= __put_user(0, &frame->uc.uc_link);
 883        err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
 884        err |= __put_user(sas_ss_flags(regs->r12), &frame->uc.uc_stack.ss_flags);
 885        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
 886        err |= setup_sigcontext_ia32(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]);
 887        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 888        if (err)
 889                goto give_sigsegv;
 890
 891        /* Set up to return from userspace.  If provided, use a stub
 892           already in userspace.  */
 893        if (ka->sa.sa_flags & SA_RESTORER) {
 894                unsigned int restorer = IA32_SA_RESTORER(ka);
 895                err |= __put_user(restorer, &frame->pretcode);
 896        } else {
 897                /* Pointing to rt_restorer in ia32 gate page */
 898                err |= __put_user(IA32_GATE_OFFSET + 8, &frame->pretcode);
 899        }
 900
 901        /* This is movl $,%eax ; int $0x80
 902         * and there for historical reasons only.
 903         * See arch/i386/kernel/signal.c
 904         */
 905
 906        err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
 907        err |= __put_user(__IA32_NR_rt_sigreturn, (int __user *)(frame->retcode+1));
 908        err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
 909
 910        if (err)
 911                goto give_sigsegv;
 912
 913        /* Set up registers for signal handler */
 914        regs->r12 = (unsigned long) frame;
 915        regs->cr_iip = IA32_SA_HANDLER(ka);
 916
 917        set_fs(USER_DS);
 918
 919#if 0
 920        regs->eflags &= ~TF_MASK;
 921#endif
 922
 923#if 0
 924        printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
 925               current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode);
 926#endif
 927
 928        return 1;
 929
 930give_sigsegv:
 931        force_sigsegv(sig, current);
 932        return 0;
 933}
 934
 935int
 936ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
 937                   sigset_t *set, struct pt_regs *regs)
 938{
 939       /* Set up the stack frame */
 940       if (ka->sa.sa_flags & SA_SIGINFO)
 941               return setup_rt_frame_ia32(sig, ka, info, set, regs);
 942       else
 943               return setup_frame_ia32(sig, ka, set, regs);
 944}
 945
 946asmlinkage long
 947sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
 948                 int arg6, int arg7, struct pt_regs regs)
 949{
 950        unsigned long esp = (unsigned int) regs.r12;
 951        struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(esp - 8);
 952        sigset_t set;
 953        int eax;
 954
 955        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 956                goto badframe;
 957
 958        if (__get_user(set.sig[0], &frame->sc.oldmask)
 959            || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask,
 960                                                         sizeof(frame->extramask))))
 961                goto badframe;
 962
 963        sigdelsetmask(&set, ~_BLOCKABLE);
 964        spin_lock_irq(&current->sighand->siglock);
 965        current->blocked = set;
 966        recalc_sigpending();
 967        spin_unlock_irq(&current->sighand->siglock);
 968
 969        if (restore_sigcontext_ia32(&regs, &frame->sc, &eax))
 970                goto badframe;
 971        return eax;
 972
 973  badframe:
 974        force_sig(SIGSEGV, current);
 975        return 0;
 976}
 977
 978asmlinkage long
 979sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4,
 980                    int arg5, int arg6, int arg7, struct pt_regs regs)
 981{
 982        unsigned long esp = (unsigned int) regs.r12;
 983        struct rt_sigframe_ia32 __user *frame = (struct rt_sigframe_ia32 __user *)(esp - 4);
 984        sigset_t set;
 985        int eax;
 986
 987        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 988                goto badframe;
 989        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 990                goto badframe;
 991
 992        sigdelsetmask(&set, ~_BLOCKABLE);
 993        spin_lock_irq(&current->sighand->siglock);
 994        current->blocked =  set;
 995        recalc_sigpending();
 996        spin_unlock_irq(&current->sighand->siglock);
 997
 998        if (restore_sigcontext_ia32(&regs, &frame->uc.uc_mcontext, &eax))
 999                goto badframe;
1000
1001        /* It is more difficult to avoid calling this function than to
1002           call it and ignore errors.  */
1003        do_sigaltstack((stack_t __user *) &frame->uc.uc_stack, NULL, esp);
1004
1005        return eax;
1006
1007  badframe:
1008        force_sig(SIGSEGV, current);
1009        return 0;
1010}
1011