diff options
Diffstat (limited to 'arch/x86/kernel/signal.c')
-rw-r--r-- | arch/x86/kernel/signal.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index cf34eb37fbee..7fc78b019815 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -649,9 +649,16 @@ badframe: | |||
649 | } | 649 | } |
650 | 650 | ||
651 | #ifdef CONFIG_X86_32 | 651 | #ifdef CONFIG_X86_32 |
652 | asmlinkage int sys_rt_sigreturn(struct pt_regs regs) | 652 | /* |
653 | * Note: do not pass in pt_regs directly as with tail-call optimization | ||
654 | * GCC will incorrectly stomp on the caller's frame and corrupt user-space | ||
655 | * register state: | ||
656 | */ | ||
657 | asmlinkage int sys_rt_sigreturn(unsigned long __unused) | ||
653 | { | 658 | { |
654 | return do_rt_sigreturn(®s); | 659 | struct pt_regs *regs = (struct pt_regs *)&__unused; |
660 | |||
661 | return do_rt_sigreturn(regs); | ||
655 | } | 662 | } |
656 | #else /* !CONFIG_X86_32 */ | 663 | #else /* !CONFIG_X86_32 */ |
657 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | 664 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) |