aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/signal_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/signal_64.c')
-rw-r--r--arch/powerpc/kernel/signal_64.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 23ba69c26913..66a5fbe31989 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -141,9 +141,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
141 unsigned long err = 0; 141 unsigned long err = 0;
142 unsigned long save_r13 = 0; 142 unsigned long save_r13 = 0;
143 elf_greg_t *gregs = (elf_greg_t *)regs; 143 elf_greg_t *gregs = (elf_greg_t *)regs;
144#ifdef CONFIG_ALTIVEC
145 unsigned long msr; 144 unsigned long msr;
146#endif
147 int i; 145 int i;
148 146
149 /* If this is not a signal return, we preserve the TLS in r13 */ 147 /* If this is not a signal return, we preserve the TLS in r13 */
@@ -154,7 +152,12 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
154 err |= __copy_from_user(regs, &sc->gp_regs, 152 err |= __copy_from_user(regs, &sc->gp_regs,
155 PT_MSR*sizeof(unsigned long)); 153 PT_MSR*sizeof(unsigned long));
156 154
157 /* skip MSR and SOFTE */ 155 /* get MSR separately, transfer the LE bit if doing signal return */
156 err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
157 if (sig)
158 regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
159
160 /* skip SOFTE */
158 for (i = PT_MSR+1; i <= PT_RESULT; i++) { 161 for (i = PT_MSR+1; i <= PT_RESULT; i++) {
159 if (i == PT_SOFTE) 162 if (i == PT_SOFTE)
160 continue; 163 continue;
@@ -179,7 +182,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
179 182
180#ifdef CONFIG_ALTIVEC 183#ifdef CONFIG_ALTIVEC
181 err |= __get_user(v_regs, &sc->v_regs); 184 err |= __get_user(v_regs, &sc->v_regs);
182 err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
183 if (err) 185 if (err)
184 return err; 186 return err;
185 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ 187 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
@@ -410,6 +412,8 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
410 412
411 /* Set up "regs" so we "return" to the signal handler. */ 413 /* Set up "regs" so we "return" to the signal handler. */
412 err |= get_user(regs->nip, &funct_desc_ptr->entry); 414 err |= get_user(regs->nip, &funct_desc_ptr->entry);
415 /* enter the signal handler in big-endian mode */
416 regs->msr &= ~MSR_LE;
413 regs->gpr[1] = newsp; 417 regs->gpr[1] = newsp;
414 err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); 418 err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
415 regs->gpr[3] = signr; 419 regs->gpr[3] = signr;