powerpc: signals: Stop using current in signal code
[cascardo/linux.git] / arch / powerpc / kernel / signal_32.c
index a7daf74..9637f8e 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/vdso.h>
 #include <asm/switch_to.h>
 #include <asm/tm.h>
+#include <asm/asm-prototypes.h>
 #ifdef CONFIG_PPC64
 #include "ppc32.h"
 #include <asm/unistd.h>
@@ -698,6 +699,7 @@ static long restore_user_regs(struct pt_regs *regs,
                if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
                                     sizeof(sr->mc_vregs)))
                        return 1;
+               current->thread.used_vr = true;
        } else if (current->thread.used_vr)
                memset(&current->thread.vr_state, 0,
                       ELF_NVRREG * sizeof(vector128));
@@ -724,6 +726,7 @@ static long restore_user_regs(struct pt_regs *regs,
                 */
                if (copy_vsx_from_user(current, &sr->mc_vsregs))
                        return 1;
+               current->thread.used_vsr = true;
        } else if (current->thread.used_vsr)
                for (i = 0; i < 32 ; i++)
                        current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
@@ -743,6 +746,7 @@ static long restore_user_regs(struct pt_regs *regs,
                if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
                                     ELF_NEVRREG * sizeof(u32)))
                        return 1;
+               current->thread.used_spe = true;
        } else if (current->thread.used_spe)
                memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
 
@@ -799,6 +803,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
                                     &tm_sr->mc_vregs,
                                     sizeof(sr->mc_vregs)))
                        return 1;
+               current->thread.used_vr = true;
        } else if (current->thread.used_vr) {
                memset(&current->thread.vr_state, 0,
                       ELF_NVRREG * sizeof(vector128));
@@ -832,6 +837,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
                if (copy_vsx_from_user(current, &sr->mc_vsregs) ||
                    copy_transact_vsx_from_user(current, &tm_sr->mc_vsregs))
                        return 1;
+               current->thread.used_vsr = true;
        } else if (current->thread.used_vsr)
                for (i = 0; i < 32 ; i++) {
                        current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
@@ -848,6 +854,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
                if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
                                     ELF_NEVRREG * sizeof(u32)))
                        return 1;
+               current->thread.used_spe = true;
        } else if (current->thread.used_spe)
                memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
 
@@ -971,7 +978,7 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
  * (one which gets siginfo).
  */
 int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
-                      struct pt_regs *regs)
+                      struct task_struct *tsk)
 {
        struct rt_sigframe __user *rt_sf;
        struct mcontext __user *frame;
@@ -980,10 +987,13 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
        unsigned long newsp = 0;
        int sigret;
        unsigned long tramp;
+       struct pt_regs *regs = tsk->thread.regs;
+
+       BUG_ON(tsk != current);
 
        /* Set up Signal Frame */
        /* Put a Real Time Context onto stack */
-       rt_sf = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*rt_sf), 1);
+       rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1);
        addr = rt_sf;
        if (unlikely(rt_sf == NULL))
                goto badframe;
@@ -1000,9 +1010,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
        /* Save user registers on the stack */
        frame = &rt_sf->uc.uc_mcontext;
        addr = frame;
-       if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
+       if (vdso32_rt_sigtramp && tsk->mm->context.vdso_base) {
                sigret = 0;
-               tramp = current->mm->context.vdso_base + vdso32_rt_sigtramp;
+               tramp = tsk->mm->context.vdso_base + vdso32_rt_sigtramp;
        } else {
                sigret = __NR_rt_sigreturn;
                tramp = (unsigned long) frame->tramp;
@@ -1029,7 +1039,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
        }
        regs->link = tramp;
 
-       current->thread.fp_state.fpscr = 0;     /* turn off all fp exceptions */
+       tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
 
        /* create a stack frame for the caller of the handler */
        newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
@@ -1054,7 +1064,7 @@ badframe:
                printk_ratelimited(KERN_INFO
                                   "%s[%d]: bad frame in handle_rt_signal32: "
                                   "%p nip %08lx lr %08lx\n",
-                                  current->comm, current->pid,
+                                  tsk->comm, tsk->pid,
                                   addr, regs->nip, regs->link);
 
        return 1;
@@ -1410,7 +1420,8 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
 /*
  * OK, we're invoking a handler
  */
-int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs)
+int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
+               struct task_struct *tsk)
 {
        struct sigcontext __user *sc;
        struct sigframe __user *frame;
@@ -1418,9 +1429,12 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs
        unsigned long newsp = 0;
        int sigret;
        unsigned long tramp;
+       struct pt_regs *regs = tsk->thread.regs;
+
+       BUG_ON(tsk != current);
 
        /* Set up Signal Frame */
-       frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 1);
+       frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1);
        if (unlikely(frame == NULL))
                goto badframe;
        sc = (struct sigcontext __user *) &frame->sctx;
@@ -1439,9 +1453,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs
            || __put_user(ksig->sig, &sc->signal))
                goto badframe;
 
-       if (vdso32_sigtramp && current->mm->context.vdso_base) {
+       if (vdso32_sigtramp && tsk->mm->context.vdso_base) {
                sigret = 0;
-               tramp = current->mm->context.vdso_base + vdso32_sigtramp;
+               tramp = tsk->mm->context.vdso_base + vdso32_sigtramp;
        } else {
                sigret = __NR_sigreturn;
                tramp = (unsigned long) frame->mctx.tramp;
@@ -1463,7 +1477,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs
 
        regs->link = tramp;
 
-       current->thread.fp_state.fpscr = 0;     /* turn off all fp exceptions */
+       tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
 
        /* create a stack frame for the caller of the handler */
        newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
@@ -1483,7 +1497,7 @@ badframe:
                printk_ratelimited(KERN_INFO
                                   "%s[%d]: bad frame in handle_signal32: "
                                   "%p nip %08lx lr %08lx\n",
-                                  current->comm, current->pid,
+                                  tsk->comm, tsk->pid,
                                   frame, regs->nip, regs->link);
 
        return 1;