diff options
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 59 |
1 files changed, 23 insertions, 36 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 5a2eba60dd39..c9d02751127f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -76,7 +76,6 @@ | |||
76 | * registers from *regs. This is what we need | 76 | * registers from *regs. This is what we need |
77 | * to do when a signal has been delivered. | 77 | * to do when a signal has been delivered. |
78 | */ | 78 | */ |
79 | #define sigreturn_exit(regs) return 0 | ||
80 | 79 | ||
81 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) | 80 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) |
82 | #undef __SIGNAL_FRAMESIZE | 81 | #undef __SIGNAL_FRAMESIZE |
@@ -156,9 +155,17 @@ static inline int save_general_regs(struct pt_regs *regs, | |||
156 | elf_greg_t64 *gregs = (elf_greg_t64 *)regs; | 155 | elf_greg_t64 *gregs = (elf_greg_t64 *)regs; |
157 | int i; | 156 | int i; |
158 | 157 | ||
159 | for (i = 0; i <= PT_RESULT; i ++) | 158 | if (!FULL_REGS(regs)) { |
159 | set_thread_flag(TIF_SAVE_NVGPRS); | ||
160 | current_thread_info()->nvgprs_frame = frame->mc_gregs; | ||
161 | } | ||
162 | |||
163 | for (i = 0; i <= PT_RESULT; i ++) { | ||
164 | if (i == 14 && !FULL_REGS(regs)) | ||
165 | i = 32; | ||
160 | if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i])) | 166 | if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i])) |
161 | return -EFAULT; | 167 | return -EFAULT; |
168 | } | ||
162 | return 0; | 169 | return 0; |
163 | } | 170 | } |
164 | 171 | ||
@@ -179,8 +186,6 @@ static inline int restore_general_regs(struct pt_regs *regs, | |||
179 | 186 | ||
180 | #else /* CONFIG_PPC64 */ | 187 | #else /* CONFIG_PPC64 */ |
181 | 188 | ||
182 | extern void sigreturn_exit(struct pt_regs *); | ||
183 | |||
184 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) | 189 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) |
185 | 190 | ||
186 | static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) | 191 | static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) |
@@ -256,8 +261,10 @@ long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, | |||
256 | while (1) { | 261 | while (1) { |
257 | current->state = TASK_INTERRUPTIBLE; | 262 | current->state = TASK_INTERRUPTIBLE; |
258 | schedule(); | 263 | schedule(); |
259 | if (do_signal(&saveset, regs)) | 264 | if (do_signal(&saveset, regs)) { |
260 | sigreturn_exit(regs); | 265 | set_thread_flag(TIF_RESTOREALL); |
266 | return 0; | ||
267 | } | ||
261 | } | 268 | } |
262 | } | 269 | } |
263 | 270 | ||
@@ -292,8 +299,10 @@ long sys_rt_sigsuspend( | |||
292 | while (1) { | 299 | while (1) { |
293 | current->state = TASK_INTERRUPTIBLE; | 300 | current->state = TASK_INTERRUPTIBLE; |
294 | schedule(); | 301 | schedule(); |
295 | if (do_signal(&saveset, regs)) | 302 | if (do_signal(&saveset, regs)) { |
296 | sigreturn_exit(regs); | 303 | set_thread_flag(TIF_RESTOREALL); |
304 | return 0; | ||
305 | } | ||
297 | } | 306 | } |
298 | } | 307 | } |
299 | 308 | ||
@@ -391,9 +400,6 @@ struct rt_sigframe { | |||
391 | static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, | 400 | static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, |
392 | int sigret) | 401 | int sigret) |
393 | { | 402 | { |
394 | #ifdef CONFIG_PPC32 | ||
395 | CHECK_FULL_REGS(regs); | ||
396 | #endif | ||
397 | /* Make sure floating point registers are stored in regs */ | 403 | /* Make sure floating point registers are stored in regs */ |
398 | flush_fp_to_thread(current); | 404 | flush_fp_to_thread(current); |
399 | 405 | ||
@@ -828,12 +834,6 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, | |||
828 | regs->gpr[6] = (unsigned long) rt_sf; | 834 | regs->gpr[6] = (unsigned long) rt_sf; |
829 | regs->nip = (unsigned long) ka->sa.sa_handler; | 835 | regs->nip = (unsigned long) ka->sa.sa_handler; |
830 | regs->trap = 0; | 836 | regs->trap = 0; |
831 | #ifdef CONFIG_PPC64 | ||
832 | regs->result = 0; | ||
833 | |||
834 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
835 | ptrace_notify(SIGTRAP); | ||
836 | #endif | ||
837 | return 1; | 837 | return 1; |
838 | 838 | ||
839 | badframe: | 839 | badframe: |
@@ -911,8 +911,8 @@ long sys_swapcontext(struct ucontext __user *old_ctx, | |||
911 | */ | 911 | */ |
912 | if (do_setcontext(new_ctx, regs, 0)) | 912 | if (do_setcontext(new_ctx, regs, 0)) |
913 | do_exit(SIGSEGV); | 913 | do_exit(SIGSEGV); |
914 | sigreturn_exit(regs); | 914 | |
915 | /* doesn't actually return back to here */ | 915 | set_thread_flag(TIF_RESTOREALL); |
916 | return 0; | 916 | return 0; |
917 | } | 917 | } |
918 | 918 | ||
@@ -945,12 +945,11 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | |||
945 | * nobody does any... | 945 | * nobody does any... |
946 | */ | 946 | */ |
947 | compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); | 947 | compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); |
948 | return (int)regs->result; | ||
949 | #else | 948 | #else |
950 | do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); | 949 | do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); |
951 | sigreturn_exit(regs); /* doesn't return here */ | ||
952 | return 0; | ||
953 | #endif | 950 | #endif |
951 | set_thread_flag(TIF_RESTOREALL); | ||
952 | return 0; | ||
954 | 953 | ||
955 | bad: | 954 | bad: |
956 | force_sig(SIGSEGV, current); | 955 | force_sig(SIGSEGV, current); |
@@ -1041,9 +1040,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx, | |||
1041 | */ | 1040 | */ |
1042 | do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); | 1041 | do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); |
1043 | 1042 | ||
1044 | sigreturn_exit(regs); | 1043 | set_thread_flag(TIF_RESTOREALL); |
1045 | /* doesn't actually return back to here */ | ||
1046 | |||
1047 | out: | 1044 | out: |
1048 | return 0; | 1045 | return 0; |
1049 | } | 1046 | } |
@@ -1107,12 +1104,6 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
1107 | regs->gpr[4] = (unsigned long) sc; | 1104 | regs->gpr[4] = (unsigned long) sc; |
1108 | regs->nip = (unsigned long) ka->sa.sa_handler; | 1105 | regs->nip = (unsigned long) ka->sa.sa_handler; |
1109 | regs->trap = 0; | 1106 | regs->trap = 0; |
1110 | #ifdef CONFIG_PPC64 | ||
1111 | regs->result = 0; | ||
1112 | |||
1113 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
1114 | ptrace_notify(SIGTRAP); | ||
1115 | #endif | ||
1116 | 1107 | ||
1117 | return 1; | 1108 | return 1; |
1118 | 1109 | ||
@@ -1160,12 +1151,8 @@ long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | |||
1160 | || restore_user_regs(regs, sr, 1)) | 1151 | || restore_user_regs(regs, sr, 1)) |
1161 | goto badframe; | 1152 | goto badframe; |
1162 | 1153 | ||
1163 | #ifdef CONFIG_PPC64 | 1154 | set_thread_flag(TIF_RESTOREALL); |
1164 | return (int)regs->result; | ||
1165 | #else | ||
1166 | sigreturn_exit(regs); /* doesn't return */ | ||
1167 | return 0; | 1155 | return 0; |
1168 | #endif | ||
1169 | 1156 | ||
1170 | badframe: | 1157 | badframe: |
1171 | force_sig(SIGSEGV, current); | 1158 | force_sig(SIGSEGV, current); |