diff options
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 22f078984845..237faeec2ec2 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))) |
@@ -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 | ||
@@ -1047,6 +1052,8 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
1047 | regs->gpr[3] = sig; | 1052 | regs->gpr[3] = sig; |
1048 | regs->gpr[4] = (unsigned long) sc; | 1053 | regs->gpr[4] = (unsigned long) sc; |
1049 | regs->nip = (unsigned long) ka->sa.sa_handler; | 1054 | regs->nip = (unsigned long) ka->sa.sa_handler; |
1055 | /* enter the signal handler in big-endian mode */ | ||
1056 | regs->msr &= ~MSR_LE; | ||
1050 | regs->trap = 0; | 1057 | regs->trap = 0; |
1051 | 1058 | ||
1052 | return 1; | 1059 | return 1; |