]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] consolidate arch specific copy_siginfo_to_user
authorStephen Rothwell <sfr@canb.auug.org.au>
Tue, 28 May 2002 12:51:30 +0000 (05:51 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 28 May 2002 12:51:30 +0000 (05:51 -0700)
This patch moves a version of copy_siginfo_to_user that is common to
ten of our architectures into the gerneic code and allows the other
architectures to override it.  I suspect more of the remaining
architectures will be able to use it as well once it is fixed (patch
to follow).

18 files changed:
arch/arm/kernel/signal.c
arch/i386/kernel/signal.c
arch/m68k/kernel/signal.c
arch/mips/kernel/signal.c
arch/ppc/kernel/signal.c
arch/ppc64/kernel/signal.c
arch/s390/kernel/signal.c
arch/s390x/kernel/signal.c
arch/sh/kernel/signal.c
arch/x86_64/kernel/signal.c
include/asm-alpha/siginfo.h
include/asm-cris/siginfo.h
include/asm-ia64/siginfo.h
include/asm-mips64/siginfo.h
include/asm-parisc/siginfo.h
include/asm-sparc/siginfo.h
include/asm-sparc64/siginfo.h
kernel/signal.c

index fa5df23bf4c0a92399a4d831c0cbf865f86005b5..19f19865c7ccc9ebee4c468414e3bea8fcc9e54f 100644 (file)
@@ -51,42 +51,6 @@ static const unsigned long retcodes[4] = {
 
 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       int err = -EFAULT;;
-
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               goto out;
-
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-
-       /* If you change siginfo_t structure, please be sure
-          this code is fixed accordingly.
-          It should never copy any pad contained in the structure
-          to avoid security leaks, but must copy the generic
-          3 ints plus the relevant union member.  */
-       err = __put_user(from->si_signo, &to->si_signo);
-       err |= __put_user(from->si_errno, &to->si_errno);
-       err |= __put_user((short)from->si_code, &to->si_code);
-       /* First 32bits of unions are always present.  */
-       err |= __put_user(from->si_pid, &to->si_pid);
-       switch (from->si_code >> 16) {
-       case __SI_FAULT >> 16:
-               break;
-       case __SI_CHLD >> 16:
-               err |= __put_user(from->si_utime, &to->si_utime);
-               err |= __put_user(from->si_stime, &to->si_stime);
-               err |= __put_user(from->si_status, &to->si_status);
-       default:
-               err |= __put_user(from->si_uid, &to->si_uid);
-               break;
-       /* case __SI_RT: This is not generated by the kernel as of now.  */
-       }
-out:
-       return err;
-}
-
 /*
  * atomically swap in the new signal mask, and wait for a signal.
  */
index 981bf811e1b595d196be1b49cec7092db2ee1150..6bc90370e56334804c810f0aabc902829f0774ed 100644 (file)
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
index a5d4061dde2853b0f57105918e1d1d0b97c87a64..bedc542cc23491ab4386ba5692fe411dffeb7243 100644 (file)
@@ -190,41 +190,6 @@ struct rt_sigframe
 };
 
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 static unsigned char fpu_version = 0;  /* version number of fpu, set by setup_frame */
 
 static inline int restore_fpu_state(struct sigcontext *sc)
index b5ad2cc6015a4ddac0798e5f49873e781bfca6db..fa143d4785fc4d7a55d5db7e75df0756f5563c59 100644 (file)
@@ -37,41 +37,6 @@ extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
 
 extern asmlinkage void syscall_trace(void);
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
index 1e3c0b19ce7743d73744af742dd1fc3a8cb23ebf..3702f8ef4c7b7c8ed7e9d0210f24ae4be0e0dfeb 100644 (file)
@@ -62,41 +62,6 @@ extern void sigreturn_exit(struct pt_regs *);
 
 int do_signal(sigset_t *oldset, struct pt_regs *regs);
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
index d70a7f622a7ec9fef8db08ad9eb2b51ef4b75bc8..5318026e5874c502af5b3034979ba0367973305e 100644 (file)
@@ -65,41 +65,6 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs);
 extern long sys_wait4(pid_t pid, unsigned int *stat_addr,
                     int options, /*unsigned long*/ struct rusage *ru);
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
index d7d2e47c770ecdbdcb8b76cf646c6b7c03118e1e..bf453c691c38935a4834464d84f49b360f7d3ca3 100644 (file)
@@ -49,41 +49,6 @@ typedef struct
 
 asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
index 022b4f00f20ceb6b41f3097d5d85be83fad79356..b3279a47b7392482a1b4e6431bbecb16fae9d7a6 100644 (file)
@@ -49,41 +49,6 @@ typedef struct
 
 asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
index 93c6b3d7f359cf55806dee64f8ae818b5ea0d91a..b25359b1aba346460fdbc54ee2ceeed3bb4ed25a 100644 (file)
 
 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
index 5f4006335cfc1346bb1591985a30dcb767ee5529..5066784dad1cf5adc097f456ff645bc4ed2abba6 100644 (file)
@@ -39,41 +39,6 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 void ia32_setup_frame(int sig, struct k_sigaction *ka,
             sigset_t *set, struct pt_regs * regs); 
 
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now.  */
-               }
-               return err;
-       }
-}
-
 asmlinkage long
 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs)
 {
index b6ff2471d9dfb07d9802bab14e7f34363ed179db..5e5e59d8142993365f1c0d1fd6d0fb4515afd5d3 100644 (file)
@@ -227,6 +227,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
                memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
 }
 
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
 extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
 
 #endif /* __KERNEL__ */
index d843ace9c962cb79e895d30e86ae7e960cd3d9b0..6938a2b738c835a73dd67508a43687c4ccc0458f 100644 (file)
@@ -226,6 +226,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
                memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
 }
 
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
 extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
 
 #endif /* __KERNEL__ */
index bfe08f5097eee55d1cbae11d63d05e45e97fc9ae..0fba20e4d47cceb5d089c240bd276e8f7c08bb79 100644 (file)
@@ -271,6 +271,7 @@ copy_siginfo (siginfo_t *to, siginfo_t *from)
                memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
 }
 
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
 extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
 extern int copy_siginfo_from_user(siginfo_t *to, siginfo_t *from);
 
index 0a10716d6ab9818bf98a19cbdb29a80181aea98e..2c5233efb6d939a11afaf16d595c5cc8ee645d8d 100644 (file)
@@ -248,6 +248,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
                memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
 }
 
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
 extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
 
 #endif /* __KERNEL__ */
index 349b614eca38b70e1ad5314494be04a816f62a0a..6c41fb2f8e5686aacc730a23acb890288ac2838c 100644 (file)
@@ -228,6 +228,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
                memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
 }
 
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
 extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
 
 #endif /* __KERNEL__ */
index 7ea5b45db59ed3d02a2385ce091a987a58a0f986..302e2bcb8139de2377fe898c319e24b8ac664868 100644 (file)
@@ -236,6 +236,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
                memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
 }
 
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
 extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
 
 #endif /* __KERNEL__ */
index daaf3beff68de9b6740a44cdac32915248983e04..12187839d1cfb5a690dd2088af65b64fa3013c0d 100644 (file)
@@ -311,6 +311,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
                memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
 }
 
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
 extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
 extern int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from);
 
index d45a2da06ad0a763e84d8607d85aaffe121dd4dd..f195db26ed91e8ba8c187bf9678c670950509a63 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/fs.h>
 
 #include <asm/uaccess.h>
+#include <asm/siginfo.h>
 
 /*
  * SLAB caches for signal bits.
@@ -932,6 +933,45 @@ sys_rt_sigpending(sigset_t *set, size_t sigsetsize)
        return do_sigpending(set, sigsetsize);
 }
 
+#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+               return -EFAULT;
+       if (from->si_code < 0)
+               return __copy_to_user(to, from, sizeof(siginfo_t));
+       else {
+               int err;
+
+               /* If you change siginfo_t structure, please be sure
+                  this code is fixed accordingly.
+                  It should never copy any pad contained in the structure
+                  to avoid security leaks, but must copy the generic
+                  3 ints plus the relevant union member.  */
+               err = __put_user(from->si_signo, &to->si_signo);
+               err |= __put_user(from->si_errno, &to->si_errno);
+               err |= __put_user((short)from->si_code, &to->si_code);
+               /* First 32bits of unions are always present.  */
+               err |= __put_user(from->si_pid, &to->si_pid);
+               switch (from->si_code >> 16) {
+               case __SI_FAULT >> 16:
+                       break;
+               case __SI_CHLD >> 16:
+                       err |= __put_user(from->si_utime, &to->si_utime);
+                       err |= __put_user(from->si_stime, &to->si_stime);
+                       err |= __put_user(from->si_status, &to->si_status);
+               default:
+                       err |= __put_user(from->si_uid, &to->si_uid);
+                       break;
+               /* case __SI_RT: This is not generated by the kernel as of now.  */
+               }
+               return err;
+       }
+}
+
+#endif
+
 asmlinkage long
 sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
                    const struct timespec *uts, size_t sigsetsize)