diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2011-08-18 15:10:29 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2011-11-02 09:15:19 -0400 |
commit | fbe9868693d9025753427d7d28b9eed4d01cf674 (patch) | |
tree | 47a05225f617f1b0b69b35aefb2f20bd28de4269 /arch | |
parent | c7ea591c91162a203a5961d69f5c86a6ef9d50c1 (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.c | 39 | ||||
-rw-r--r-- | arch/x86/um/signal_64.c | 33 |
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 | ||
217 | static int copy_sc_to_user(struct sigcontext __user *to, | 217 | static 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 = ¤t->thread.arch.faultinfo; | 221 | struct faultinfo * fi = ¤t->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, ¤t->thread.regs, sp); | 293 | err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->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 | |||
382 | err: | ||
383 | PT_REGS_SP(regs) = save_sp; | ||
384 | return err; | ||
385 | } | 369 | } |
386 | 370 | ||
387 | int setup_signal_stack_si(unsigned long stack_top, int sig, | 371 | int 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 | |||
439 | err: | ||
440 | PT_REGS_SP(regs) = save_sp; | ||
441 | return err; | ||
442 | } | 419 | } |
443 | 420 | ||
444 | long sys_sigreturn(struct pt_regs regs) | 421 | long 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 | ||
69 | static int copy_sc_to_user(struct sigcontext __user *to, | 69 | static 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 = ¤t->thread.arch.faultinfo; | 73 | struct faultinfo * fi = ¤t->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 | |||
226 | restore_sp: | ||
227 | PT_REGS_RSP(regs) = save_sp; | ||
228 | return err; | ||
229 | } | 210 | } |
230 | 211 | ||
231 | long sys_rt_sigreturn(struct pt_regs *regs) | 212 | long sys_rt_sigreturn(struct pt_regs *regs) |