aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 21:05:28 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 21:05:28 -0500
commit54d46ea993744c5408e39ce0cb4851e13cbea716 (patch)
tree8e38fa92cc2ae72e0353c44e1e68be9bf5a7a058 /arch/x86
parentf59dc2bb5a50b26ea751f9eac1c81e4cc7de5257 (diff)
parent50ececcfa7d1acee085b2c518cad495062db6379 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull signal handling cleanups from Al Viro: "sigaltstack infrastructure + conversion for x86, alpha and um, COMPAT_SYSCALL_DEFINE infrastructure. Note that there are several conflicts between "unify SS_ONSTACK/SS_DISABLE definitions" and UAPI patches in mainline; resolution is trivial - just remove definitions of SS_ONSTACK and SS_DISABLED from arch/*/uapi/asm/signal.h; they are all identical and include/uapi/linux/signal.h contains the unified variant." Fixed up conflicts as per Al. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: alpha: switch to generic sigaltstack new helpers: __save_altstack/__compat_save_altstack, switch x86 and um to those generic compat_sys_sigaltstack() introduce generic sys_sigaltstack(), switch x86 and um to it new helper: compat_user_stack_pointer() new helper: restore_altstack() unify SS_ONSTACK/SS_DISABLE definitions new helper: current_user_stack_pointer() missing user_stack_pointer() instances Bury the conditionals from kernel_thread/kernel_execve series COMPAT_SYSCALL_DEFINE: infrastructure
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Kconfig3
-rw-r--r--arch/x86/ia32/ia32_signal.c55
-rw-r--r--arch/x86/ia32/ia32entry.S1
-rw-r--r--arch/x86/include/asm/ia32.h10
-rw-r--r--arch/x86/include/asm/ptrace.h7
-rw-r--r--arch/x86/include/asm/sys_ia32.h2
-rw-r--r--arch/x86/include/asm/syscalls.h3
-rw-r--r--arch/x86/include/asm/unistd.h1
-rw-r--r--arch/x86/include/uapi/asm/signal.h6
-rw-r--r--arch/x86/kernel/entry_32.S1
-rw-r--r--arch/x86/kernel/entry_64.S3
-rw-r--r--arch/x86/kernel/signal.c29
-rw-r--r--arch/x86/syscalls/syscall_32.tbl2
-rw-r--r--arch/x86/syscalls/syscall_64.tbl4
-rw-r--r--arch/x86/um/Kconfig3
-rw-r--r--arch/x86/um/asm/ptrace.h1
-rw-r--r--arch/x86/um/signal.c9
-rw-r--r--arch/x86/um/sys_call_table_32.c1
-rw-r--r--arch/x86/um/sys_call_table_64.c1
19 files changed, 24 insertions, 118 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 97f8c5ad8c2d..79795af59810 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -110,11 +110,10 @@ config X86
110 select GENERIC_STRNLEN_USER 110 select GENERIC_STRNLEN_USER
111 select HAVE_CONTEXT_TRACKING if X86_64 111 select HAVE_CONTEXT_TRACKING if X86_64
112 select HAVE_IRQ_TIME_ACCOUNTING 112 select HAVE_IRQ_TIME_ACCOUNTING
113 select GENERIC_KERNEL_THREAD
114 select GENERIC_KERNEL_EXECVE
115 select MODULES_USE_ELF_REL if X86_32 113 select MODULES_USE_ELF_REL if X86_32
116 select MODULES_USE_ELF_RELA if X86_64 114 select MODULES_USE_ELF_RELA if X86_64
117 select CLONE_BACKWARDS if X86_32 115 select CLONE_BACKWARDS if X86_32
116 select GENERIC_SIGALTSTACK
118 117
119config INSTRUCTION_DECODER 118config INSTRUCTION_DECODER
120 def_bool y 119 def_bool y
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index efc6a958b71d..a1daf4a65009 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -136,52 +136,6 @@ asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
136 return sigsuspend(&blocked); 136 return sigsuspend(&blocked);
137} 137}
138 138
139asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
140 stack_ia32_t __user *uoss_ptr,
141 struct pt_regs *regs)
142{
143 stack_t uss, uoss;
144 int ret, err = 0;
145 mm_segment_t seg;
146
147 if (uss_ptr) {
148 u32 ptr;
149
150 memset(&uss, 0, sizeof(stack_t));
151 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
152 return -EFAULT;
153
154 get_user_try {
155 get_user_ex(ptr, &uss_ptr->ss_sp);
156 get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
157 get_user_ex(uss.ss_size, &uss_ptr->ss_size);
158 } get_user_catch(err);
159
160 if (err)
161 return -EFAULT;
162 uss.ss_sp = compat_ptr(ptr);
163 }
164 seg = get_fs();
165 set_fs(KERNEL_DS);
166 ret = do_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
167 (stack_t __force __user *) &uoss, regs->sp);
168 set_fs(seg);
169 if (ret >= 0 && uoss_ptr) {
170 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
171 return -EFAULT;
172
173 put_user_try {
174 put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
175 put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
176 put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
177 } put_user_catch(err);
178
179 if (err)
180 ret = -EFAULT;
181 }
182 return ret;
183}
184
185/* 139/*
186 * Do a signal return; undo the signal stack. 140 * Do a signal return; undo the signal stack.
187 */ 141 */
@@ -292,7 +246,6 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
292 struct rt_sigframe_ia32 __user *frame; 246 struct rt_sigframe_ia32 __user *frame;
293 sigset_t set; 247 sigset_t set;
294 unsigned int ax; 248 unsigned int ax;
295 struct pt_regs tregs;
296 249
297 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4); 250 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
298 251
@@ -306,8 +259,7 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
306 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) 259 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
307 goto badframe; 260 goto badframe;
308 261
309 tregs = *regs; 262 if (compat_restore_altstack(&frame->uc.uc_stack))
310 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
311 goto badframe; 263 goto badframe;
312 264
313 return ax; 265 return ax;
@@ -515,10 +467,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
515 else 467 else
516 put_user_ex(0, &frame->uc.uc_flags); 468 put_user_ex(0, &frame->uc.uc_flags);
517 put_user_ex(0, &frame->uc.uc_link); 469 put_user_ex(0, &frame->uc.uc_link);
518 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 470 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
519 put_user_ex(sas_ss_flags(regs->sp),
520 &frame->uc.uc_stack.ss_flags);
521 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
522 471
523 if (ka->sa.sa_flags & SA_RESTORER) 472 if (ka->sa.sa_flags & SA_RESTORER)
524 restorer = ka->sa.sa_restorer; 473 restorer = ka->sa.sa_restorer;
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 32e6f05ddaaa..102ff7cb3e41 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -464,7 +464,6 @@ GLOBAL(\label)
464 464
465 PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi 465 PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
466 PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi 466 PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
467 PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
468 PTREGSCALL stub32_execve, compat_sys_execve, %rcx 467 PTREGSCALL stub32_execve, compat_sys_execve, %rcx
469 PTREGSCALL stub32_fork, sys_fork, %rdi 468 PTREGSCALL stub32_fork, sys_fork, %rdi
470 PTREGSCALL stub32_vfork, sys_vfork, %rdi 469 PTREGSCALL stub32_vfork, sys_vfork, %rdi
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index e6232773ce49..4c6da2e4bb1d 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -29,16 +29,10 @@ struct old_sigaction32 {
29 unsigned int sa_restorer; /* Another 32 bit pointer */ 29 unsigned int sa_restorer; /* Another 32 bit pointer */
30}; 30};
31 31
32typedef struct sigaltstack_ia32 {
33 unsigned int ss_sp;
34 int ss_flags;
35 unsigned int ss_size;
36} stack_ia32_t;
37
38struct ucontext_ia32 { 32struct ucontext_ia32 {
39 unsigned int uc_flags; 33 unsigned int uc_flags;
40 unsigned int uc_link; 34 unsigned int uc_link;
41 stack_ia32_t uc_stack; 35 compat_stack_t uc_stack;
42 struct sigcontext_ia32 uc_mcontext; 36 struct sigcontext_ia32 uc_mcontext;
43 compat_sigset_t uc_sigmask; /* mask last for extensibility */ 37 compat_sigset_t uc_sigmask; /* mask last for extensibility */
44}; 38};
@@ -46,7 +40,7 @@ struct ucontext_ia32 {
46struct ucontext_x32 { 40struct ucontext_x32 {
47 unsigned int uc_flags; 41 unsigned int uc_flags;
48 unsigned int uc_link; 42 unsigned int uc_link;
49 stack_ia32_t uc_stack; 43 compat_stack_t uc_stack;
50 unsigned int uc__pad0; /* needed for alignment */ 44 unsigned int uc__pad0; /* needed for alignment */
51 struct sigcontext uc_mcontext; /* the 64-bit sigcontext type */ 45 struct sigcontext uc_mcontext; /* the 64-bit sigcontext type */
52 compat_sigset_t uc_sigmask; /* mask last for extensibility */ 46 compat_sigset_t uc_sigmask; /* mask last for extensibility */
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index 03ca442d8f0d..942a08623a1a 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -133,6 +133,13 @@ static inline bool user_64bit_mode(struct pt_regs *regs)
133 return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs; 133 return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
134#endif 134#endif
135} 135}
136
137#define current_user_stack_pointer() this_cpu_read(old_rsp)
138/* ia32 vs. x32 difference */
139#define compat_user_stack_pointer() \
140 (test_thread_flag(TIF_IA32) \
141 ? current_pt_regs()->sp \
142 : this_cpu_read(old_rsp))
136#endif 143#endif
137 144
138#ifdef CONFIG_X86_32 145#ifdef CONFIG_X86_32
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index c76fae4d90be..31f61f96e0fb 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -69,8 +69,6 @@ asmlinkage long sys32_fallocate(int, int, unsigned,
69 69
70/* ia32/ia32_signal.c */ 70/* ia32/ia32_signal.c */
71asmlinkage long sys32_sigsuspend(int, int, old_sigset_t); 71asmlinkage long sys32_sigsuspend(int, int, old_sigset_t);
72asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *,
73 stack_ia32_t __user *, struct pt_regs *);
74asmlinkage long sys32_sigreturn(struct pt_regs *); 72asmlinkage long sys32_sigreturn(struct pt_regs *);
75asmlinkage long sys32_rt_sigreturn(struct pt_regs *); 73asmlinkage long sys32_rt_sigreturn(struct pt_regs *);
76 74
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 2f8374718aa3..58b7e3eac0ae 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -25,9 +25,6 @@ asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
25 25
26/* kernel/signal.c */ 26/* kernel/signal.c */
27long sys_rt_sigreturn(struct pt_regs *); 27long sys_rt_sigreturn(struct pt_regs *);
28long sys_sigaltstack(const stack_t __user *, stack_t __user *,
29 struct pt_regs *);
30
31 28
32/* kernel/tls.c */ 29/* kernel/tls.c */
33asmlinkage int sys_set_thread_area(struct user_desc __user *); 30asmlinkage int sys_set_thread_area(struct user_desc __user *);
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 1003e69a40d9..a0790e07ba65 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -48,7 +48,6 @@
48# define __ARCH_WANT_SYS_TIME 48# define __ARCH_WANT_SYS_TIME
49# define __ARCH_WANT_SYS_UTIME 49# define __ARCH_WANT_SYS_UTIME
50# define __ARCH_WANT_SYS_WAITPID 50# define __ARCH_WANT_SYS_WAITPID
51# define __ARCH_WANT_SYS_EXECVE
52# define __ARCH_WANT_SYS_FORK 51# define __ARCH_WANT_SYS_FORK
53# define __ARCH_WANT_SYS_VFORK 52# define __ARCH_WANT_SYS_VFORK
54# define __ARCH_WANT_SYS_CLONE 53# define __ARCH_WANT_SYS_CLONE
diff --git a/arch/x86/include/uapi/asm/signal.h b/arch/x86/include/uapi/asm/signal.h
index 0818f9a8e889..aa7d6ae39e0e 100644
--- a/arch/x86/include/uapi/asm/signal.h
+++ b/arch/x86/include/uapi/asm/signal.h
@@ -87,12 +87,6 @@ typedef unsigned long sigset_t;
87 87
88#define SA_RESTORER 0x04000000 88#define SA_RESTORER 0x04000000
89 89
90/*
91 * sigaltstack controls
92 */
93#define SS_ONSTACK 1
94#define SS_DISABLE 2
95
96#define MINSIGSTKSZ 2048 90#define MINSIGSTKSZ 2048
97#define SIGSTKSZ 8192 91#define SIGSTKSZ 8192
98 92
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index c763116c5359..ff84d5469d77 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -739,7 +739,6 @@ ENTRY(ptregs_##name) ; \
739ENDPROC(ptregs_##name) 739ENDPROC(ptregs_##name)
740 740
741PTREGSCALL1(iopl) 741PTREGSCALL1(iopl)
742PTREGSCALL2(sigaltstack)
743PTREGSCALL0(sigreturn) 742PTREGSCALL0(sigreturn)
744PTREGSCALL0(rt_sigreturn) 743PTREGSCALL0(rt_sigreturn)
745PTREGSCALL2(vm86) 744PTREGSCALL2(vm86)
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 70641aff0c25..07a7a04529bc 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -864,7 +864,6 @@ END(stub_\func)
864 FORK_LIKE clone 864 FORK_LIKE clone
865 FORK_LIKE fork 865 FORK_LIKE fork
866 FORK_LIKE vfork 866 FORK_LIKE vfork
867 PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
868 PTREGSCALL stub_iopl, sys_iopl, %rsi 867 PTREGSCALL stub_iopl, sys_iopl, %rsi
869 868
870ENTRY(ptregscall_common) 869ENTRY(ptregscall_common)
@@ -913,8 +912,6 @@ ENTRY(stub_rt_sigreturn)
913END(stub_rt_sigreturn) 912END(stub_rt_sigreturn)
914 913
915#ifdef CONFIG_X86_X32_ABI 914#ifdef CONFIG_X86_X32_ABI
916 PTREGSCALL stub_x32_sigaltstack, sys32_sigaltstack, %rdx
917
918ENTRY(stub_x32_rt_sigreturn) 915ENTRY(stub_x32_rt_sigreturn)
919 CFI_STARTPROC 916 CFI_STARTPROC
920 addq $8, %rsp 917 addq $8, %rsp
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index fbbb604313a2..d6bf1f34a6e9 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -364,10 +364,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
364 else 364 else
365 put_user_ex(0, &frame->uc.uc_flags); 365 put_user_ex(0, &frame->uc.uc_flags);
366 put_user_ex(0, &frame->uc.uc_link); 366 put_user_ex(0, &frame->uc.uc_link);
367 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 367 err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
368 put_user_ex(sas_ss_flags(regs->sp),
369 &frame->uc.uc_stack.ss_flags);
370 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
371 368
372 /* Set up to return from userspace. */ 369 /* Set up to return from userspace. */
373 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); 370 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
@@ -414,7 +411,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
414 struct rt_sigframe __user *frame; 411 struct rt_sigframe __user *frame;
415 void __user *fp = NULL; 412 void __user *fp = NULL;
416 int err = 0; 413 int err = 0;
417 struct task_struct *me = current;
418 414
419 frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp); 415 frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp);
420 416
@@ -433,10 +429,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
433 else 429 else
434 put_user_ex(0, &frame->uc.uc_flags); 430 put_user_ex(0, &frame->uc.uc_flags);
435 put_user_ex(0, &frame->uc.uc_link); 431 put_user_ex(0, &frame->uc.uc_link);
436 put_user_ex(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 432 err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
437 put_user_ex(sas_ss_flags(regs->sp),
438 &frame->uc.uc_stack.ss_flags);
439 put_user_ex(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
440 433
441 /* Set up to return from userspace. If provided, use a stub 434 /* Set up to return from userspace. If provided, use a stub
442 already in userspace. */ 435 already in userspace. */
@@ -503,10 +496,7 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
503 else 496 else
504 put_user_ex(0, &frame->uc.uc_flags); 497 put_user_ex(0, &frame->uc.uc_flags);
505 put_user_ex(0, &frame->uc.uc_link); 498 put_user_ex(0, &frame->uc.uc_link);
506 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 499 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
507 put_user_ex(sas_ss_flags(regs->sp),
508 &frame->uc.uc_stack.ss_flags);
509 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
510 put_user_ex(0, &frame->uc.uc__pad0); 500 put_user_ex(0, &frame->uc.uc__pad0);
511 501
512 if (ka->sa.sa_flags & SA_RESTORER) { 502 if (ka->sa.sa_flags & SA_RESTORER) {
@@ -603,13 +593,6 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
603} 593}
604#endif /* CONFIG_X86_32 */ 594#endif /* CONFIG_X86_32 */
605 595
606long
607sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
608 struct pt_regs *regs)
609{
610 return do_sigaltstack(uss, uoss, regs->sp);
611}
612
613/* 596/*
614 * Do a signal return; undo the signal stack. 597 * Do a signal return; undo the signal stack.
615 */ 598 */
@@ -659,7 +642,7 @@ long sys_rt_sigreturn(struct pt_regs *regs)
659 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) 642 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
660 goto badframe; 643 goto badframe;
661 644
662 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) 645 if (restore_altstack(&frame->uc.uc_stack))
663 goto badframe; 646 goto badframe;
664 647
665 return ax; 648 return ax;
@@ -865,7 +848,6 @@ asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs)
865 struct rt_sigframe_x32 __user *frame; 848 struct rt_sigframe_x32 __user *frame;
866 sigset_t set; 849 sigset_t set;
867 unsigned long ax; 850 unsigned long ax;
868 struct pt_regs tregs;
869 851
870 frame = (struct rt_sigframe_x32 __user *)(regs->sp - 8); 852 frame = (struct rt_sigframe_x32 __user *)(regs->sp - 8);
871 853
@@ -879,8 +861,7 @@ asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs)
879 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) 861 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
880 goto badframe; 862 goto badframe;
881 863
882 tregs = *regs; 864 if (compat_restore_altstack(&frame->uc.uc_stack))
883 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
884 goto badframe; 865 goto badframe;
885 866
886 return ax; 867 return ax;
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index 05f404f53f59..28e3fa9056ea 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -192,7 +192,7 @@
192183 i386 getcwd sys_getcwd 192183 i386 getcwd sys_getcwd
193184 i386 capget sys_capget 193184 i386 capget sys_capget
194185 i386 capset sys_capset 194185 i386 capset sys_capset
195186 i386 sigaltstack ptregs_sigaltstack stub32_sigaltstack 195186 i386 sigaltstack sys_sigaltstack compat_sys_sigaltstack
196187 i386 sendfile sys_sendfile sys32_sendfile 196187 i386 sendfile sys_sendfile sys32_sendfile
197188 i386 getpmsg 197188 i386 getpmsg
198189 i386 putpmsg 198189 i386 putpmsg
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index 7c58c84b7bc8..dc97328bd90a 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -137,7 +137,7 @@
137128 64 rt_sigtimedwait sys_rt_sigtimedwait 137128 64 rt_sigtimedwait sys_rt_sigtimedwait
138129 64 rt_sigqueueinfo sys_rt_sigqueueinfo 138129 64 rt_sigqueueinfo sys_rt_sigqueueinfo
139130 common rt_sigsuspend sys_rt_sigsuspend 139130 common rt_sigsuspend sys_rt_sigsuspend
140131 64 sigaltstack stub_sigaltstack 140131 64 sigaltstack sys_sigaltstack
141132 common utime sys_utime 141132 common utime sys_utime
142133 common mknod sys_mknod 142133 common mknod sys_mknod
143134 64 uselib 143134 64 uselib
@@ -338,7 +338,7 @@
338522 x32 rt_sigpending sys32_rt_sigpending 338522 x32 rt_sigpending sys32_rt_sigpending
339523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait 339523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait
340524 x32 rt_sigqueueinfo sys32_rt_sigqueueinfo 340524 x32 rt_sigqueueinfo sys32_rt_sigqueueinfo
341525 x32 sigaltstack stub_x32_sigaltstack 341525 x32 sigaltstack compat_sys_sigaltstack
342526 x32 timer_create compat_sys_timer_create 342526 x32 timer_create compat_sys_timer_create
343527 x32 mq_notify compat_sys_mq_notify 343527 x32 mq_notify compat_sys_mq_notify
344528 x32 kexec_load compat_sys_kexec_load 344528 x32 kexec_load compat_sys_kexec_load
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index 983997041963..53c90fd412d1 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -13,8 +13,7 @@ endmenu
13config UML_X86 13config UML_X86
14 def_bool y 14 def_bool y
15 select GENERIC_FIND_FIRST_BIT 15 select GENERIC_FIND_FIRST_BIT
16 select GENERIC_KERNEL_THREAD 16 select GENERIC_SIGALTSTACK
17 select GENERIC_KERNEL_EXECVE
18 17
19config 64BIT 18config 64BIT
20 bool "64-bit kernel" if SUBARCH = "x86" 19 bool "64-bit kernel" if SUBARCH = "x86"
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index 755133258c45..54f8102ccde5 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -86,4 +86,5 @@ extern long arch_prctl(struct task_struct *task, int code,
86 unsigned long __user *addr); 86 unsigned long __user *addr);
87 87
88#endif 88#endif
89#define user_stack_pointer(regs) PT_REGS_SP(regs)
89#endif /* __UM_X86_PTRACE_H */ 90#endif /* __UM_X86_PTRACE_H */
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index bdaa08cfbcf4..71cef48ea5cd 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -342,9 +342,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc,
342{ 342{
343 int err = 0; 343 int err = 0;
344 344
345 err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); 345 err |= __save_altstack(&uc->uc_stack, sp);
346 err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
347 err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
348 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, 0); 346 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, 0);
349 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); 347 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
350 return err; 348 return err;
@@ -529,10 +527,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
529 /* Create the ucontext. */ 527 /* Create the ucontext. */
530 err |= __put_user(0, &frame->uc.uc_flags); 528 err |= __put_user(0, &frame->uc.uc_flags);
531 err |= __put_user(0, &frame->uc.uc_link); 529 err |= __put_user(0, &frame->uc.uc_link);
532 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 530 err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
533 err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)),
534 &frame->uc.uc_stack.ss_flags);
535 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
536 err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, 531 err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
537 set->sig[0]); 532 set->sig[0]);
538 err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); 533 err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
index 812e98c098e4..a0c3b0d1a122 100644
--- a/arch/x86/um/sys_call_table_32.c
+++ b/arch/x86/um/sys_call_table_32.c
@@ -27,7 +27,6 @@
27#define ptregs_iopl sys_iopl 27#define ptregs_iopl sys_iopl
28#define ptregs_vm86old sys_vm86old 28#define ptregs_vm86old sys_vm86old
29#define ptregs_vm86 sys_vm86 29#define ptregs_vm86 sys_vm86
30#define ptregs_sigaltstack sys_sigaltstack
31 30
32#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void sym(void) ; 31#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void sym(void) ;
33#include <asm/syscalls_32.h> 32#include <asm/syscalls_32.h>
diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c
index 170bd926a69c..f2f0723070ca 100644
--- a/arch/x86/um/sys_call_table_64.c
+++ b/arch/x86/um/sys_call_table_64.c
@@ -31,7 +31,6 @@
31#define stub_fork sys_fork 31#define stub_fork sys_fork
32#define stub_vfork sys_vfork 32#define stub_vfork sys_vfork
33#define stub_execve sys_execve 33#define stub_execve sys_execve
34#define stub_sigaltstack sys_sigaltstack
35#define stub_rt_sigreturn sys_rt_sigreturn 34#define stub_rt_sigreturn sys_rt_sigreturn
36 35
37#define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat) 36#define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat)