aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/signal_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r--arch/powerpc/kernel/signal_32.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 8fdeca2d4597..d73b25e22fca 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -419,9 +419,7 @@ static long restore_user_regs(struct pt_regs *regs,
419{ 419{
420 long err; 420 long err;
421 unsigned int save_r2 = 0; 421 unsigned int save_r2 = 0;
422#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
423 unsigned long msr; 422 unsigned long msr;
424#endif
425 423
426 /* 424 /*
427 * restore general registers but not including MSR or SOFTE. Also 425 * restore general registers but not including MSR or SOFTE. Also
@@ -430,11 +428,16 @@ static long restore_user_regs(struct pt_regs *regs,
430 if (!sig) 428 if (!sig)
431 save_r2 = (unsigned int)regs->gpr[2]; 429 save_r2 = (unsigned int)regs->gpr[2];
432 err = restore_general_regs(regs, sr); 430 err = restore_general_regs(regs, sr);
431 err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
433 if (!sig) 432 if (!sig)
434 regs->gpr[2] = (unsigned long) save_r2; 433 regs->gpr[2] = (unsigned long) save_r2;
435 if (err) 434 if (err)
436 return 1; 435 return 1;
437 436
437 /* if doing signal return, restore the previous little-endian mode */
438 if (sig)
439 regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
440
438 /* 441 /*
439 * Do this before updating the thread state in 442 * Do this before updating the thread state in
440 * current->thread.fpr/vr/evr. That way, if we get preempted 443 * current->thread.fpr/vr/evr. That way, if we get preempted
@@ -455,7 +458,7 @@ static long restore_user_regs(struct pt_regs *regs,
455 /* force the process to reload the altivec registers from 458 /* force the process to reload the altivec registers from
456 current->thread when it next does altivec instructions */ 459 current->thread when it next does altivec instructions */
457 regs->msr &= ~MSR_VEC; 460 regs->msr &= ~MSR_VEC;
458 if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) { 461 if (msr & MSR_VEC) {
459 /* restore altivec registers from the stack */ 462 /* restore altivec registers from the stack */
460 if (__copy_from_user(current->thread.vr, &sr->mc_vregs, 463 if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
461 sizeof(sr->mc_vregs))) 464 sizeof(sr->mc_vregs)))
@@ -472,7 +475,7 @@ static long restore_user_regs(struct pt_regs *regs,
472 /* force the process to reload the spe registers from 475 /* force the process to reload the spe registers from
473 current->thread when it next does spe instructions */ 476 current->thread when it next does spe instructions */
474 regs->msr &= ~MSR_SPE; 477 regs->msr &= ~MSR_SPE;
475 if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) { 478 if (msr & MSR_SPE) {
476 /* restore spe registers from the stack */ 479 /* restore spe registers from the stack */
477 if (__copy_from_user(current->thread.evr, &sr->mc_vregs, 480 if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
478 ELF_NEVRREG * sizeof(u32))) 481 ELF_NEVRREG * sizeof(u32)))
@@ -757,10 +760,10 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
757 760
758 /* Save user registers on the stack */ 761 /* Save user registers on the stack */
759 frame = &rt_sf->uc.uc_mcontext; 762 frame = &rt_sf->uc.uc_mcontext;
760 if (vdso32_rt_sigtramp && current->thread.vdso_base) { 763 if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
761 if (save_user_regs(regs, frame, 0)) 764 if (save_user_regs(regs, frame, 0))
762 goto badframe; 765 goto badframe;
763 regs->link = current->thread.vdso_base + vdso32_rt_sigtramp; 766 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
764 } else { 767 } else {
765 if (save_user_regs(regs, frame, __NR_rt_sigreturn)) 768 if (save_user_regs(regs, frame, __NR_rt_sigreturn))
766 goto badframe; 769 goto badframe;
@@ -777,6 +780,8 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
777 regs->gpr[5] = (unsigned long) &rt_sf->uc; 780 regs->gpr[5] = (unsigned long) &rt_sf->uc;
778 regs->gpr[6] = (unsigned long) rt_sf; 781 regs->gpr[6] = (unsigned long) rt_sf;
779 regs->nip = (unsigned long) ka->sa.sa_handler; 782 regs->nip = (unsigned long) ka->sa.sa_handler;
783 /* enter the signal handler in big-endian mode */
784 regs->msr &= ~MSR_LE;
780 regs->trap = 0; 785 regs->trap = 0;
781 return 1; 786 return 1;
782 787
@@ -1038,10 +1043,10 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
1038 || __put_user(sig, &sc->signal)) 1043 || __put_user(sig, &sc->signal))
1039 goto badframe; 1044 goto badframe;
1040 1045
1041 if (vdso32_sigtramp && current->thread.vdso_base) { 1046 if (vdso32_sigtramp && current->mm->context.vdso_base) {
1042 if (save_user_regs(regs, &frame->mctx, 0)) 1047 if (save_user_regs(regs, &frame->mctx, 0))
1043 goto badframe; 1048 goto badframe;
1044 regs->link = current->thread.vdso_base + vdso32_sigtramp; 1049 regs->link = current->mm->context.vdso_base + vdso32_sigtramp;
1045 } else { 1050 } else {
1046 if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) 1051 if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
1047 goto badframe; 1052 goto badframe;
@@ -1056,6 +1061,8 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
1056 regs->gpr[3] = sig; 1061 regs->gpr[3] = sig;
1057 regs->gpr[4] = (unsigned long) sc; 1062 regs->gpr[4] = (unsigned long) sc;
1058 regs->nip = (unsigned long) ka->sa.sa_handler; 1063 regs->nip = (unsigned long) ka->sa.sa_handler;
1064 /* enter the signal handler in big-endian mode */
1065 regs->msr &= ~MSR_LE;
1059 regs->trap = 0; 1066 regs->trap = 0;
1060 1067
1061 return 1; 1068 return 1;