aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2011-08-18 15:10:29 -0400
committerRichard Weinberger <richard@nod.at>2011-11-02 09:15:19 -0400
commitfbe9868693d9025753427d7d28b9eed4d01cf674 (patch)
tree47a05225f617f1b0b69b35aefb2f20bd28de4269 /arch
parentc7ea591c91162a203a5961d69f5c86a6ef9d50c1 (diff)
um: no need to play with save_sp in signal frame setup anymore
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/um/signal_32.c39
-rw-r--r--arch/x86/um/signal_64.c33
2 files changed, 15 insertions, 57 deletions
diff --git a/arch/x86/um/signal_32.c b/arch/x86/um/signal_32.c
index 2eebdc05be0..7a206d8f228 100644
--- a/arch/x86/um/signal_32.c
+++ b/arch/x86/um/signal_32.c
@@ -215,8 +215,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
215} 215}
216 216
217static int copy_sc_to_user(struct sigcontext __user *to, 217static int copy_sc_to_user(struct sigcontext __user *to,
218 struct _fpstate __user *to_fp, struct pt_regs *regs, 218 struct _fpstate __user *to_fp, struct pt_regs *regs)
219 unsigned long sp)
220{ 219{
221 struct sigcontext sc; 220 struct sigcontext sc;
222 struct faultinfo * fi = &current->thread.arch.faultinfo; 221 struct faultinfo * fi = &current->thread.arch.faultinfo;
@@ -230,7 +229,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
230 sc.di = REGS_EDI(regs->regs.gp); 229 sc.di = REGS_EDI(regs->regs.gp);
231 sc.si = REGS_ESI(regs->regs.gp); 230 sc.si = REGS_ESI(regs->regs.gp);
232 sc.bp = REGS_EBP(regs->regs.gp); 231 sc.bp = REGS_EBP(regs->regs.gp);
233 sc.sp = sp; 232 sc.sp = REGS_SP(regs->regs.gp);
234 sc.bx = REGS_EBX(regs->regs.gp); 233 sc.bx = REGS_EBX(regs->regs.gp);
235 sc.dx = REGS_EDX(regs->regs.gp); 234 sc.dx = REGS_EDX(regs->regs.gp);
236 sc.cx = REGS_ECX(regs->regs.gp); 235 sc.cx = REGS_ECX(regs->regs.gp);
@@ -291,7 +290,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc,
291 err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); 290 err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
292 err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); 291 err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
293 err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); 292 err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
294 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, sp); 293 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs);
295 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); 294 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
296 return err; 295 return err;
297} 296}
@@ -324,7 +323,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
324{ 323{
325 struct sigframe __user *frame; 324 struct sigframe __user *frame;
326 void __user *restorer; 325 void __user *restorer;
327 unsigned long save_sp = PT_REGS_SP(regs);
328 int err = 0; 326 int err = 0;
329 327
330 /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ 328 /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
@@ -337,19 +335,9 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
337 if (ka->sa.sa_flags & SA_RESTORER) 335 if (ka->sa.sa_flags & SA_RESTORER)
338 restorer = ka->sa.sa_restorer; 336 restorer = ka->sa.sa_restorer;
339 337
340 /* Update SP now because the page fault handler refuses to extend
341 * the stack if the faulting address is too far below the current
342 * SP, which frame now certainly is. If there's an error, the original
343 * value is restored on the way out.
344 * When writing the sigcontext to the stack, we have to write the
345 * original value, so that's passed to copy_sc_to_user, which does
346 * the right thing with it.
347 */
348 PT_REGS_SP(regs) = (unsigned long) frame;
349
350 err |= __put_user(restorer, &frame->pretcode); 338 err |= __put_user(restorer, &frame->pretcode);
351 err |= __put_user(sig, &frame->sig); 339 err |= __put_user(sig, &frame->sig);
352 err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp); 340 err |= copy_sc_to_user(&frame->sc, NULL, regs);
353 err |= __put_user(mask->sig[0], &frame->sc.oldmask); 341 err |= __put_user(mask->sig[0], &frame->sc.oldmask);
354 if (_NSIG_WORDS > 1) 342 if (_NSIG_WORDS > 1)
355 err |= __copy_to_user(&frame->extramask, &mask->sig[1], 343 err |= __copy_to_user(&frame->extramask, &mask->sig[1],
@@ -367,7 +355,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
367 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); 355 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
368 356
369 if (err) 357 if (err)
370 goto err; 358 return err;
371 359
372 PT_REGS_SP(regs) = (unsigned long) frame; 360 PT_REGS_SP(regs) = (unsigned long) frame;
373 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; 361 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
@@ -378,10 +366,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
378 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) 366 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
379 ptrace_notify(SIGTRAP); 367 ptrace_notify(SIGTRAP);
380 return 0; 368 return 0;
381
382err:
383 PT_REGS_SP(regs) = save_sp;
384 return err;
385} 369}
386 370
387int setup_signal_stack_si(unsigned long stack_top, int sig, 371int setup_signal_stack_si(unsigned long stack_top, int sig,
@@ -390,7 +374,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
390{ 374{
391 struct rt_sigframe __user *frame; 375 struct rt_sigframe __user *frame;
392 void __user *restorer; 376 void __user *restorer;
393 unsigned long save_sp = PT_REGS_SP(regs);
394 int err = 0; 377 int err = 0;
395 378
396 stack_top &= -8UL; 379 stack_top &= -8UL;
@@ -402,16 +385,13 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
402 if (ka->sa.sa_flags & SA_RESTORER) 385 if (ka->sa.sa_flags & SA_RESTORER)
403 restorer = ka->sa.sa_restorer; 386 restorer = ka->sa.sa_restorer;
404 387
405 /* See comment above about why this is here */
406 PT_REGS_SP(regs) = (unsigned long) frame;
407
408 err |= __put_user(restorer, &frame->pretcode); 388 err |= __put_user(restorer, &frame->pretcode);
409 err |= __put_user(sig, &frame->sig); 389 err |= __put_user(sig, &frame->sig);
410 err |= __put_user(&frame->info, &frame->pinfo); 390 err |= __put_user(&frame->info, &frame->pinfo);
411 err |= __put_user(&frame->uc, &frame->puc); 391 err |= __put_user(&frame->uc, &frame->puc);
412 err |= copy_siginfo_to_user(&frame->info, info); 392 err |= copy_siginfo_to_user(&frame->info, info);
413 err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, 393 err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
414 save_sp); 394 PT_REGS_SP(regs));
415 395
416 /* 396 /*
417 * This is movl $,%eax ; int $0x80 397 * This is movl $,%eax ; int $0x80
@@ -425,8 +405,9 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
425 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); 405 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
426 406
427 if (err) 407 if (err)
428 goto err; 408 return err;
429 409
410 PT_REGS_SP(regs) = (unsigned long) frame;
430 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; 411 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
431 PT_REGS_EAX(regs) = (unsigned long) sig; 412 PT_REGS_EAX(regs) = (unsigned long) sig;
432 PT_REGS_EDX(regs) = (unsigned long) &frame->info; 413 PT_REGS_EDX(regs) = (unsigned long) &frame->info;
@@ -435,10 +416,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
435 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) 416 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
436 ptrace_notify(SIGTRAP); 417 ptrace_notify(SIGTRAP);
437 return 0; 418 return 0;
438
439err:
440 PT_REGS_SP(regs) = save_sp;
441 return err;
442} 419}
443 420
444long sys_sigreturn(struct pt_regs regs) 421long sys_sigreturn(struct pt_regs regs)
diff --git a/arch/x86/um/signal_64.c b/arch/x86/um/signal_64.c
index 4e5b9b07a8c..74c2598b0b3 100644
--- a/arch/x86/um/signal_64.c
+++ b/arch/x86/um/signal_64.c
@@ -68,7 +68,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
68 68
69static int copy_sc_to_user(struct sigcontext __user *to, 69static int copy_sc_to_user(struct sigcontext __user *to,
70 struct _fpstate __user *to_fp, struct pt_regs *regs, 70 struct _fpstate __user *to_fp, struct pt_regs *regs,
71 unsigned long mask, unsigned long sp) 71 unsigned long mask)
72{ 72{
73 struct faultinfo * fi = &current->thread.arch.faultinfo; 73 struct faultinfo * fi = &current->thread.arch.faultinfo;
74 struct sigcontext sc; 74 struct sigcontext sc;
@@ -81,11 +81,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
81 PUTREG(DI, di); 81 PUTREG(DI, di);
82 PUTREG(SI, si); 82 PUTREG(SI, si);
83 PUTREG(BP, bp); 83 PUTREG(BP, bp);
84 /* 84 PUTREG(SP, sp);
85 * Must use original RSP, which is passed in, rather than what's in
86 * signal frame.
87 */
88 sc.sp = sp;
89 PUTREG(BX, bx); 85 PUTREG(BX, bx);
90 PUTREG(DX, dx); 86 PUTREG(DX, dx);
91 PUTREG(CX, cx); 87 PUTREG(CX, cx);
@@ -141,7 +137,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
141 siginfo_t *info, sigset_t *set) 137 siginfo_t *info, sigset_t *set)
142{ 138{
143 struct rt_sigframe __user *frame; 139 struct rt_sigframe __user *frame;
144 unsigned long save_sp = PT_REGS_RSP(regs);
145 int err = 0; 140 int err = 0;
146 struct task_struct *me = current; 141 struct task_struct *me = current;
147 142
@@ -159,26 +154,15 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
159 goto out; 154 goto out;
160 } 155 }
161 156
162 /*
163 * Update SP now because the page fault handler refuses to extend
164 * the stack if the faulting address is too far below the current
165 * SP, which frame now certainly is. If there's an error, the original
166 * value is restored on the way out.
167 * When writing the sigcontext to the stack, we have to write the
168 * original value, so that's passed to copy_sc_to_user, which does
169 * the right thing with it.
170 */
171 PT_REGS_RSP(regs) = (unsigned long) frame;
172
173 /* Create the ucontext. */ 157 /* Create the ucontext. */
174 err |= __put_user(0, &frame->uc.uc_flags); 158 err |= __put_user(0, &frame->uc.uc_flags);
175 err |= __put_user(0, &frame->uc.uc_link); 159 err |= __put_user(0, &frame->uc.uc_link);
176 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 160 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
177 err |= __put_user(sas_ss_flags(save_sp), 161 err |= __put_user(sas_ss_flags(PT_REGS_RSP(regs)),
178 &frame->uc.uc_stack.ss_flags); 162 &frame->uc.uc_stack.ss_flags);
179 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); 163 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
180 err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, 164 err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
181 set->sig[0], save_sp); 165 set->sig[0]);
182 err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); 166 err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
183 if (sizeof(*set) == 16) { 167 if (sizeof(*set) == 16) {
184 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); 168 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
@@ -197,10 +181,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
197 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); 181 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
198 else 182 else
199 /* could use a vstub here */ 183 /* could use a vstub here */
200 goto restore_sp; 184 return err;
201 185
202 if (err) 186 if (err)
203 goto restore_sp; 187 return err;
204 188
205 /* Set up registers for signal handler */ 189 /* Set up registers for signal handler */
206 { 190 {
@@ -209,6 +193,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
209 sig = ed->signal_invmap[sig]; 193 sig = ed->signal_invmap[sig];
210 } 194 }
211 195
196 PT_REGS_RSP(regs) = (unsigned long) frame;
212 PT_REGS_RDI(regs) = sig; 197 PT_REGS_RDI(regs) = sig;
213 /* In case the signal handler was declared without prototypes */ 198 /* In case the signal handler was declared without prototypes */
214 PT_REGS_RAX(regs) = 0; 199 PT_REGS_RAX(regs) = 0;
@@ -222,10 +207,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
222 PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; 207 PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
223 out: 208 out:
224 return err; 209 return err;
225
226restore_sp:
227 PT_REGS_RSP(regs) = save_sp;
228 return err;
229} 210}
230 211
231long sys_rt_sigreturn(struct pt_regs *regs) 212long sys_rt_sigreturn(struct pt_regs *regs)