linux/arch/parisc/kernel/signal32.c
<<
>>
Prefs
   1/*    Signal support for 32-bit kernel builds
   2 *
   3 *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
   4 *    Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
   5 *
   6 *    Code was mostly borrowed from kernel/signal.c.
   7 *    See kernel/signal.c for additional Copyrights.
   8 *
   9 *
  10 *    This program is free software; you can redistribute it and/or modify
  11 *    it under the terms of the GNU General Public License as published by
  12 *    the Free Software Foundation; either version 2 of the License, or
  13 *    (at your option) any later version.
  14 *
  15 *    This program is distributed in the hope that it will be useful,
  16 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 *    GNU General Public License for more details.
  19 *
  20 *    You should have received a copy of the GNU General Public License
  21 *    along with this program; if not, write to the Free Software
  22 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23 */
  24
  25#include <linux/compat.h>
  26#include <linux/module.h>
  27#include <linux/unistd.h>
  28#include <linux/init.h>
  29#include <linux/sched.h>
  30#include <linux/syscalls.h>
  31#include <linux/types.h>
  32#include <linux/errno.h>
  33
  34#include <asm/uaccess.h>
  35
  36#include "signal32.h"
  37#include "sys32.h"
  38
  39#define DEBUG_COMPAT_SIG 0 
  40#define DEBUG_COMPAT_SIG_LEVEL 2
  41
  42#if DEBUG_COMPAT_SIG
  43#define DBG(LEVEL, ...) \
  44        ((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
  45        ? printk(__VA_ARGS__) : (void) 0)
  46#else
  47#define DBG(LEVEL, ...)
  48#endif
  49
  50#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  51
  52inline void
  53sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
  54{
  55        s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
  56}
  57
  58inline void
  59sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
  60{
  61        s32->sig[0] = s64->sig[0] & 0xffffffffUL;
  62        s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
  63}
  64
  65static int
  66put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
  67{
  68        compat_sigset_t s;
  69
  70        if (sz != sizeof *set) panic("put_sigset32()");
  71        sigset_64to32(&s, set);
  72
  73        return copy_to_user(up, &s, sizeof s);
  74}
  75
  76static int
  77get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
  78{
  79        compat_sigset_t s;
  80        int r;
  81
  82        if (sz != sizeof *set) panic("put_sigset32()");
  83
  84        if ((r = copy_from_user(&s, up, sz)) == 0) {
  85                sigset_32to64(set, &s);
  86        }
  87
  88        return r;
  89}
  90
  91int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
  92                                    unsigned int sigsetsize)
  93{
  94        sigset_t old_set, new_set;
  95        int ret;
  96
  97        if (set && get_sigset32(set, &new_set, sigsetsize))
  98                return -EFAULT;
  99        
 100        KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
 101                                 oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);
 102
 103        if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
 104                return -EFAULT;
 105
 106        return ret;
 107}
 108
 109
 110int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
 111{
 112        int ret;
 113        sigset_t set;
 114
 115        KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);
 116
 117        if (!ret && put_sigset32(uset, &set, sigsetsize))
 118                return -EFAULT;
 119
 120        return ret;
 121}
 122
 123long
 124sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
 125                 size_t sigsetsize)
 126{
 127        struct k_sigaction32 new_sa32, old_sa32;
 128        struct k_sigaction new_sa, old_sa;
 129        int ret = -EINVAL;
 130
 131        if (act) {
 132                if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
 133                        return -EFAULT;
 134                new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler;
 135                new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
 136                sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask);
 137        }
 138
 139        ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
 140
 141        if (!ret && oact) {
 142                sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask);
 143                old_sa32.sa.sa_flags = old_sa.sa.sa_flags;
 144                old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler;
 145                if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa))
 146                        return -EFAULT;
 147        }
 148        return ret;
 149}
 150
 151int 
 152do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp)
 153{
 154        compat_stack_t ss32, oss32;
 155        stack_t ss, oss;
 156        stack_t *ssp = NULL, *ossp = NULL;
 157        int ret;
 158
 159        if (uss32) {
 160                if (copy_from_user(&ss32, uss32, sizeof ss32))
 161                        return -EFAULT;
 162
 163                ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp;
 164                ss.ss_flags = ss32.ss_flags;
 165                ss.ss_size = ss32.ss_size;
 166
 167                ssp = &ss;
 168        }
 169
 170        if (uoss32)
 171                ossp = &oss;
 172
 173        KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp);
 174
 175        if (!ret && uoss32) {
 176                oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
 177                oss32.ss_flags = oss.ss_flags;
 178                oss32.ss_size = oss.ss_size;
 179                if (copy_to_user(uoss32, &oss32, sizeof *uoss32))
 180                        return -EFAULT;
 181        }
 182
 183        return ret;
 184}
 185
 186long
 187restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
 188                struct pt_regs *regs)
 189{
 190        long err = 0;
 191        compat_uint_t compat_reg;
 192        compat_uint_t compat_regt;
 193        int regn;
 194        
 195        /* When loading 32-bit values into 64-bit registers make
 196           sure to clear the upper 32-bits */
 197        DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
 198        DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
 199        DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
 200        for(regn=0; regn < 32; regn++){
 201                err |= __get_user(compat_reg,&sc->sc_gr[regn]);
 202                regs->gr[regn] = compat_reg;
 203                /* Load upper half */
 204                err |= __get_user(compat_regt,&rf->rf_gr[regn]);
 205                regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
 206                DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n", 
 207                                regn, regs->gr[regn], compat_regt, compat_reg);
 208        }
 209        DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
 210        /* XXX: BE WARNED FR's are 64-BIT! */
 211        err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
 212                
 213        /* Better safe than sorry, pass __get_user two things of
 214           the same size and let gcc do the upward conversion to 
 215           64-bits */           
 216        err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
 217        /* Load upper half */
 218        err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
 219        regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
 220        DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
 221        DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n", 
 222                        &sc->sc_iaoq[0], compat_reg);
 223
 224        err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
 225        /* Load upper half */
 226        err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
 227        regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
 228        DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
 229        DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n", 
 230                        &sc->sc_iaoq[1],compat_reg);    
 231        DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n", 
 232                        regs->iaoq[0],regs->iaoq[1]);           
 233                
 234        err |= __get_user(compat_reg, &sc->sc_iasq[0]);
 235        /* Load the upper half for iasq */
 236        err |= __get_user(compat_regt, &rf->rf_iasq[0]);
 237        regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
 238        DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
 239        
 240        err |= __get_user(compat_reg, &sc->sc_iasq[1]);
 241        /* Load the upper half for iasq */
 242        err |= __get_user(compat_regt, &rf->rf_iasq[1]);
 243        regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
 244        DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
 245        DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n", 
 246                regs->iasq[0],regs->iasq[1]);           
 247
 248        err |= __get_user(compat_reg, &sc->sc_sar);
 249        /* Load the upper half for sar */
 250        err |= __get_user(compat_regt, &rf->rf_sar);
 251        regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg; 
 252        DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);  
 253        DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);                
 254        DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
 255        
 256        return err;
 257}
 258
 259/*
 260 * Set up the sigcontext structure for this process.
 261 * This is not an easy task if the kernel is 64-bit, it will require
 262 * that we examine the process personality to determine if we need to
 263 * truncate for a 32-bit userspace.
 264 */
 265long
 266setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, 
 267                struct pt_regs *regs, int in_syscall)            
 268{
 269        compat_int_t flags = 0;
 270        long err = 0;
 271        compat_uint_t compat_reg;
 272        compat_uint_t compat_regb;
 273        int regn;
 274        
 275        if (on_sig_stack((unsigned long) sc))
 276                flags |= PARISC_SC_FLAG_ONSTACK;
 277        
 278        if (in_syscall) {
 279                
 280                DBG(1,"setup_sigcontext32: in_syscall\n");
 281                
 282                flags |= PARISC_SC_FLAG_IN_SYSCALL;
 283                /* Truncate gr31 */
 284                compat_reg = (compat_uint_t)(regs->gr[31]);
 285                /* regs->iaoq is undefined in the syscall return path */
 286                err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
 287                DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
 288                                &sc->sc_iaoq[0], compat_reg);
 289                
 290                /* Store upper half */
 291                compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
 292                err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
 293                DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
 294                
 295                
 296                compat_reg = (compat_uint_t)(regs->gr[31]+4);
 297                err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
 298                DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
 299                                &sc->sc_iaoq[1], compat_reg);
 300                /* Store upper half */
 301                compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
 302                err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
 303                DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
 304                
 305                /* Truncate sr3 */
 306                compat_reg = (compat_uint_t)(regs->sr[3]);
 307                err |= __put_user(compat_reg, &sc->sc_iasq[0]);
 308                err |= __put_user(compat_reg, &sc->sc_iasq[1]);         
 309                
 310                /* Store upper half */
 311                compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
 312                err |= __put_user(compat_reg, &rf->rf_iasq[0]);
 313                err |= __put_user(compat_reg, &rf->rf_iasq[1]);         
 314                
 315                DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
 316                DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);            
 317                DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",                         
 318                        regs->gr[31], regs->gr[31]+4);
 319                
 320        } else {
 321                
 322                compat_reg = (compat_uint_t)(regs->iaoq[0]);
 323                err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
 324                DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
 325                                &sc->sc_iaoq[0], compat_reg);
 326                /* Store upper half */
 327                compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
 328                err |= __put_user(compat_reg, &rf->rf_iaoq[0]); 
 329                DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
 330                
 331                compat_reg = (compat_uint_t)(regs->iaoq[1]);
 332                err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
 333                DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
 334                                &sc->sc_iaoq[1], compat_reg);
 335                /* Store upper half */
 336                compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
 337                err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
 338                DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
 339                
 340                
 341                compat_reg = (compat_uint_t)(regs->iasq[0]);
 342                err |= __put_user(compat_reg, &sc->sc_iasq[0]);
 343                DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
 344                                &sc->sc_iasq[0], compat_reg);
 345                /* Store upper half */
 346                compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
 347                err |= __put_user(compat_reg, &rf->rf_iasq[0]);
 348                DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
 349                
 350                
 351                compat_reg = (compat_uint_t)(regs->iasq[1]);
 352                err |= __put_user(compat_reg, &sc->sc_iasq[1]);
 353                DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
 354                                &sc->sc_iasq[1], compat_reg);
 355                /* Store upper half */
 356                compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
 357                err |= __put_user(compat_reg, &rf->rf_iasq[1]);
 358                DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
 359
 360                /* Print out the IAOQ for debugging */          
 361                DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n", 
 362                        regs->iaoq[0], regs->iaoq[1]);
 363        }
 364
 365        err |= __put_user(flags, &sc->sc_flags);
 366        
 367        DBG(1,"setup_sigcontext32: Truncating general registers.\n");
 368        
 369        for(regn=0; regn < 32; regn++){
 370                /* Truncate a general register */
 371                compat_reg = (compat_uint_t)(regs->gr[regn]);
 372                err |= __put_user(compat_reg, &sc->sc_gr[regn]);
 373                /* Store upper half */
 374                compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
 375                err |= __put_user(compat_regb, &rf->rf_gr[regn]);
 376
 377                /* DEBUG: Write out the "upper / lower" register data */
 378                DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn, 
 379                                compat_regb, compat_reg);
 380        }
 381        
 382        /* Copy the floating point registers (same size)
 383           XXX: BE WARNED FR's are 64-BIT! */   
 384        DBG(1,"setup_sigcontext32: Copying from regs to sc, "
 385              "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
 386                sizeof(regs->fr), sizeof(sc->sc_fr));
 387        err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
 388
 389        compat_reg = (compat_uint_t)(regs->sar);
 390        err |= __put_user(compat_reg, &sc->sc_sar);
 391        DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
 392        /* Store upper half */
 393        compat_reg = (compat_uint_t)(regs->sar >> 32);
 394        err |= __put_user(compat_reg, &rf->rf_sar);     
 395        DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
 396        DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
 397
 398        return err;
 399}
 400
 401int
 402copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
 403{
 404        compat_uptr_t addr;
 405        int err;
 406
 407        if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
 408                return -EFAULT;
 409
 410        err = __get_user(to->si_signo, &from->si_signo);
 411        err |= __get_user(to->si_errno, &from->si_errno);
 412        err |= __get_user(to->si_code, &from->si_code);
 413
 414        if (to->si_code < 0)
 415                err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 416        else {
 417                switch (to->si_code >> 16) {
 418                      case __SI_CHLD >> 16:
 419                        err |= __get_user(to->si_utime, &from->si_utime);
 420                        err |= __get_user(to->si_stime, &from->si_stime);
 421                        err |= __get_user(to->si_status, &from->si_status);
 422                      default:
 423                        err |= __get_user(to->si_pid, &from->si_pid);
 424                        err |= __get_user(to->si_uid, &from->si_uid);
 425                        break;
 426                      case __SI_FAULT >> 16:
 427                        err |= __get_user(addr, &from->si_addr);
 428                        to->si_addr = compat_ptr(addr);
 429                        break;
 430                      case __SI_POLL >> 16:
 431                        err |= __get_user(to->si_band, &from->si_band);
 432                        err |= __get_user(to->si_fd, &from->si_fd);
 433                        break;
 434                      case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 435                      case __SI_MESGQ >> 16:
 436                        err |= __get_user(to->si_pid, &from->si_pid);
 437                        err |= __get_user(to->si_uid, &from->si_uid);
 438                        err |= __get_user(to->si_int, &from->si_int);
 439                        break;
 440                }
 441        }
 442        return err;
 443}
 444
 445int
 446copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
 447{
 448        compat_uptr_t addr;
 449        compat_int_t val;
 450        int err;
 451
 452        if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 453                return -EFAULT;
 454
 455        /* If you change siginfo_t structure, please be sure
 456           this code is fixed accordingly.
 457           It should never copy any pad contained in the structure
 458           to avoid security leaks, but must copy the generic
 459           3 ints plus the relevant union member.
 460           This routine must convert siginfo from 64bit to 32bit as well
 461           at the same time.  */
 462        err = __put_user(from->si_signo, &to->si_signo);
 463        err |= __put_user(from->si_errno, &to->si_errno);
 464        err |= __put_user((short)from->si_code, &to->si_code);
 465        if (from->si_code < 0)
 466                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 467        else {
 468                switch (from->si_code >> 16) {
 469                case __SI_CHLD >> 16:
 470                        err |= __put_user(from->si_utime, &to->si_utime);
 471                        err |= __put_user(from->si_stime, &to->si_stime);
 472                        err |= __put_user(from->si_status, &to->si_status);
 473                default:
 474                        err |= __put_user(from->si_pid, &to->si_pid);
 475                        err |= __put_user(from->si_uid, &to->si_uid);
 476                        break;
 477                case __SI_FAULT >> 16:
 478                        addr = ptr_to_compat(from->si_addr);
 479                        err |= __put_user(addr, &to->si_addr);
 480                        break;
 481                case __SI_POLL >> 16:
 482                        err |= __put_user(from->si_band, &to->si_band);
 483                        err |= __put_user(from->si_fd, &to->si_fd);
 484                        break;
 485                case __SI_TIMER >> 16:
 486                        err |= __put_user(from->si_tid, &to->si_tid);
 487                        err |= __put_user(from->si_overrun, &to->si_overrun);
 488                        val = (compat_int_t)from->si_int;
 489                        err |= __put_user(val, &to->si_int);
 490                        break;
 491                case __SI_RT >> 16:     /* Not generated by the kernel as of now.  */
 492                case __SI_MESGQ >> 16:
 493                        err |= __put_user(from->si_uid, &to->si_uid);
 494                        err |= __put_user(from->si_pid, &to->si_pid);
 495                        val = (compat_int_t)from->si_int;
 496                        err |= __put_user(val, &to->si_int);
 497                        break;
 498                }
 499        }
 500        return err;
 501}
 502
 503asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
 504        struct compat_siginfo __user *uinfo)
 505{
 506        siginfo_t info;
 507
 508        if (copy_siginfo_from_user32(&info, uinfo))
 509                return -EFAULT;
 510
 511        /* Not even root can pretend to send signals from the kernel.
 512           Nor can they impersonate a kill(), which adds source info.  */
 513        if (info.si_code >= 0)
 514                return -EPERM;
 515        info.si_signo = sig;
 516
 517        /* POSIX.1b doesn't mention process groups.  */
 518        return kill_proc_info(sig, &info, pid);
 519}
 520
 521