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.c59
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
182extern 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
186static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) 191static 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 {
391static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, 400static 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
839badframe: 839badframe:
@@ -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
1170badframe: 1157badframe:
1171 force_sig(SIGSEGV, current); 1158 force_sig(SIGSEGV, current);