[MIPS] use compat_siginfo in rt_sigframe_n32
[sfrench/cifs-2.6.git] / arch / mips / kernel / signal_n32.c
index 7ca2a078841fb65253d5e9aeec70b8dfcebbd5c9..eb7e05926ebe359592d8fb0bc7d01e545efe76b5 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
@@ -29,6 +28,7 @@
 #include <linux/compat.h>
 #include <linux/bitops.h>
 
+#include <asm/abi.h>
 #include <asm/asm.h>
 #include <asm/cacheflush.h>
 #include <asm/compat-signal.h>
@@ -72,7 +72,7 @@ struct ucontextn32 {
 struct rt_sigframe_n32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
        u32 rs_code[2];                 /* signal trampoline */
-       struct siginfo rs_info;
+       struct compat_siginfo rs_info;
        struct ucontextn32 rs_uc;
 };
 
@@ -81,7 +81,7 @@ struct rt_sigframe_n32 {
 struct rt_sigframe_n32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
        u32 rs_pad[2];
-       struct siginfo rs_info;
+       struct compat_siginfo rs_info;
        struct ucontextn32 rs_uc;
        u32 rs_code[8] ____cacheline_aligned;           /* signal trampoline */
 };
@@ -126,6 +126,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
        sigset_t set;
        stack_t st;
        s32 sp;
+       int sig;
 
        frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -139,8 +140,11 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+       sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
+       if (sig < 0)
                goto badframe;
+       else if (sig)
+               force_sig(sig, current);
 
        /* The ucontext contains a stack32_t, so we must convert!  */
        if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
@@ -169,7 +173,7 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(struct k_sigaction * ka,
        struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
        struct rt_sigframe_n32 __user *frame;
@@ -183,7 +187,7 @@ int setup_rt_frame_n32(struct k_sigaction * ka,
        install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
 
        /* Create siginfo.  */
-       err |= copy_siginfo_to_user(&frame->rs_info, info);
+       err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -228,3 +232,8 @@ give_sigsegv:
        force_sigsegv(signr, current);
        return -EFAULT;
 }
+
+struct mips_abi mips_abi_n32 = {
+       .setup_rt_frame = setup_rt_frame_n32,
+       .restart        = __NR_N32_restart_syscall
+};