diff options
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 40 |
1 files changed, 14 insertions, 26 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 68027bfa5f8e..a67e00aa3caa 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -519,6 +519,13 @@ static int save_tm_user_regs(struct pt_regs *regs, | |||
519 | { | 519 | { |
520 | unsigned long msr = regs->msr; | 520 | unsigned long msr = regs->msr; |
521 | 521 | ||
522 | /* Remove TM bits from thread's MSR. The MSR in the sigcontext | ||
523 | * just indicates to userland that we were doing a transaction, but we | ||
524 | * don't want to return in transactional state. This also ensures | ||
525 | * that flush_fp_to_thread won't set TIF_RESTORE_TM again. | ||
526 | */ | ||
527 | regs->msr &= ~MSR_TS_MASK; | ||
528 | |||
522 | /* Make sure floating point registers are stored in regs */ | 529 | /* Make sure floating point registers are stored in regs */ |
523 | flush_fp_to_thread(current); | 530 | flush_fp_to_thread(current); |
524 | 531 | ||
@@ -1015,29 +1022,24 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
1015 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1022 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1016 | tm_frame = &rt_sf->uc_transact.uc_mcontext; | 1023 | tm_frame = &rt_sf->uc_transact.uc_mcontext; |
1017 | if (MSR_TM_ACTIVE(regs->msr)) { | 1024 | if (MSR_TM_ACTIVE(regs->msr)) { |
1025 | if (__put_user((unsigned long)&rt_sf->uc_transact, | ||
1026 | &rt_sf->uc.uc_link) || | ||
1027 | __put_user((unsigned long)tm_frame, | ||
1028 | &rt_sf->uc_transact.uc_regs)) | ||
1029 | goto badframe; | ||
1018 | if (save_tm_user_regs(regs, frame, tm_frame, sigret)) | 1030 | if (save_tm_user_regs(regs, frame, tm_frame, sigret)) |
1019 | goto badframe; | 1031 | goto badframe; |
1020 | } | 1032 | } |
1021 | else | 1033 | else |
1022 | #endif | 1034 | #endif |
1023 | { | 1035 | { |
1036 | if (__put_user(0, &rt_sf->uc.uc_link)) | ||
1037 | goto badframe; | ||
1024 | if (save_user_regs(regs, frame, tm_frame, sigret, 1)) | 1038 | if (save_user_regs(regs, frame, tm_frame, sigret, 1)) |
1025 | goto badframe; | 1039 | goto badframe; |
1026 | } | 1040 | } |
1027 | regs->link = tramp; | 1041 | regs->link = tramp; |
1028 | 1042 | ||
1029 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
1030 | if (MSR_TM_ACTIVE(regs->msr)) { | ||
1031 | if (__put_user((unsigned long)&rt_sf->uc_transact, | ||
1032 | &rt_sf->uc.uc_link) | ||
1033 | || __put_user((unsigned long)tm_frame, &rt_sf->uc_transact.uc_regs)) | ||
1034 | goto badframe; | ||
1035 | } | ||
1036 | else | ||
1037 | #endif | ||
1038 | if (__put_user(0, &rt_sf->uc.uc_link)) | ||
1039 | goto badframe; | ||
1040 | |||
1041 | current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ | 1043 | current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ |
1042 | 1044 | ||
1043 | /* create a stack frame for the caller of the handler */ | 1045 | /* create a stack frame for the caller of the handler */ |
@@ -1056,13 +1058,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
1056 | /* enter the signal handler in native-endian mode */ | 1058 | /* enter the signal handler in native-endian mode */ |
1057 | regs->msr &= ~MSR_LE; | 1059 | regs->msr &= ~MSR_LE; |
1058 | regs->msr |= (MSR_KERNEL & MSR_LE); | 1060 | regs->msr |= (MSR_KERNEL & MSR_LE); |
1059 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
1060 | /* Remove TM bits from thread's MSR. The MSR in the sigcontext | ||
1061 | * just indicates to userland that we were doing a transaction, but we | ||
1062 | * don't want to return in transactional state: | ||
1063 | */ | ||
1064 | regs->msr &= ~MSR_TS_MASK; | ||
1065 | #endif | ||
1066 | return 1; | 1061 | return 1; |
1067 | 1062 | ||
1068 | badframe: | 1063 | badframe: |
@@ -1484,13 +1479,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
1484 | regs->nip = (unsigned long) ka->sa.sa_handler; | 1479 | regs->nip = (unsigned long) ka->sa.sa_handler; |
1485 | /* enter the signal handler in big-endian mode */ | 1480 | /* enter the signal handler in big-endian mode */ |
1486 | regs->msr &= ~MSR_LE; | 1481 | regs->msr &= ~MSR_LE; |
1487 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
1488 | /* Remove TM bits from thread's MSR. The MSR in the sigcontext | ||
1489 | * just indicates to userland that we were doing a transaction, but we | ||
1490 | * don't want to return in transactional state: | ||
1491 | */ | ||
1492 | regs->msr &= ~MSR_TS_MASK; | ||
1493 | #endif | ||
1494 | return 1; | 1482 | return 1; |
1495 | 1483 | ||
1496 | badframe: | 1484 | badframe: |