diff options
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 8fdeca2d459..d73b25e22fc 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; |