diff options
author | Brian Gerst <brgerst@gmail.com> | 2009-02-10 09:51:46 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-11 06:40:45 -0500 |
commit | 253f29a4ae9cc6cdc7b94f96517f27a93885a6ce (patch) | |
tree | 09942e565938a6bac216b1725ccf607e01d09b20 /arch/x86/kernel/signal.c | |
parent | aa78bcfa01dec3cdbde3cda098ce32abbd9c3bf6 (diff) |
x86: pass in pt_regs pointer for syscalls that need it
Some syscalls need to access the pt_regs structure, either to copy
user register state or to modifiy it. This patch adds stubs to load
the address of the pt_regs struct into the %eax register, and changes
the syscalls to regparm(1) to receive the pt_regs pointer as the
first argument.
Signed-off-by: Brian Gerst <brgerst@gmail.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/signal.c')
-rw-r--r-- | arch/x86/kernel/signal.c | 35 |
1 files changed, 7 insertions, 28 deletions
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 8562387c75a7..d7a158367e38 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -549,39 +549,28 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
549 | #endif /* CONFIG_X86_32 */ | 549 | #endif /* CONFIG_X86_32 */ |
550 | 550 | ||
551 | #ifdef CONFIG_X86_32 | 551 | #ifdef CONFIG_X86_32 |
552 | asmlinkage int sys_sigaltstack(unsigned long bx) | 552 | ptregscall int |
553 | { | 553 | sys_sigaltstack(struct pt_regs *regs, const stack_t __user *uss, |
554 | /* | 554 | stack_t __user *uoss) |
555 | * This is needed to make gcc realize it doesn't own the | ||
556 | * "struct pt_regs" | ||
557 | */ | ||
558 | struct pt_regs *regs = (struct pt_regs *)&bx; | ||
559 | const stack_t __user *uss = (const stack_t __user *)bx; | ||
560 | stack_t __user *uoss = (stack_t __user *)regs->cx; | ||
561 | |||
562 | return do_sigaltstack(uss, uoss, regs->sp); | ||
563 | } | ||
564 | #else /* !CONFIG_X86_32 */ | 555 | #else /* !CONFIG_X86_32 */ |
565 | asmlinkage long | 556 | asmlinkage long |
566 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 557 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
567 | struct pt_regs *regs) | 558 | struct pt_regs *regs) |
559 | #endif /* CONFIG_X86_32 */ | ||
568 | { | 560 | { |
569 | return do_sigaltstack(uss, uoss, regs->sp); | 561 | return do_sigaltstack(uss, uoss, regs->sp); |
570 | } | 562 | } |
571 | #endif /* CONFIG_X86_32 */ | ||
572 | 563 | ||
573 | /* | 564 | /* |
574 | * Do a signal return; undo the signal stack. | 565 | * Do a signal return; undo the signal stack. |
575 | */ | 566 | */ |
576 | #ifdef CONFIG_X86_32 | 567 | #ifdef CONFIG_X86_32 |
577 | asmlinkage unsigned long sys_sigreturn(unsigned long __unused) | 568 | ptregscall unsigned long sys_sigreturn(struct pt_regs *regs) |
578 | { | 569 | { |
579 | struct sigframe __user *frame; | 570 | struct sigframe __user *frame; |
580 | struct pt_regs *regs; | ||
581 | unsigned long ax; | 571 | unsigned long ax; |
582 | sigset_t set; | 572 | sigset_t set; |
583 | 573 | ||
584 | regs = (struct pt_regs *) &__unused; | ||
585 | frame = (struct sigframe __user *)(regs->sp - 8); | 574 | frame = (struct sigframe __user *)(regs->sp - 8); |
586 | 575 | ||
587 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 576 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
@@ -640,23 +629,13 @@ badframe: | |||
640 | } | 629 | } |
641 | 630 | ||
642 | #ifdef CONFIG_X86_32 | 631 | #ifdef CONFIG_X86_32 |
643 | /* | 632 | ptregscall int sys_rt_sigreturn(struct pt_regs *regs) |
644 | * Note: do not pass in pt_regs directly as with tail-call optimization | ||
645 | * GCC will incorrectly stomp on the caller's frame and corrupt user-space | ||
646 | * register state: | ||
647 | */ | ||
648 | asmlinkage int sys_rt_sigreturn(unsigned long __unused) | ||
649 | { | ||
650 | struct pt_regs *regs = (struct pt_regs *)&__unused; | ||
651 | |||
652 | return do_rt_sigreturn(regs); | ||
653 | } | ||
654 | #else /* !CONFIG_X86_32 */ | 633 | #else /* !CONFIG_X86_32 */ |
655 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | 634 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) |
635 | #endif /* CONFIG_X86_32 */ | ||
656 | { | 636 | { |
657 | return do_rt_sigreturn(regs); | 637 | return do_rt_sigreturn(regs); |
658 | } | 638 | } |
659 | #endif /* CONFIG_X86_32 */ | ||
660 | 639 | ||
661 | /* | 640 | /* |
662 | * OK, we're invoking a handler: | 641 | * OK, we're invoking a handler: |