aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-12-23 03:41:17 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2013-02-03 18:16:17 -0500
commit99b06feb0f7c99f171cb962d0e6a17f81625abd3 (patch)
treee2d184a61dcf5b0317bfbc204c1e9e4256649b7f /arch
parent0aa0203fb43f04714004b2c4ad33b858e240555d (diff)
sparc: switch to generic sigaltstack
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/Kconfig1
-rw-r--r--arch/sparc/include/asm/compat_signal.h6
-rw-r--r--arch/sparc/kernel/entry.S8
-rw-r--r--arch/sparc/kernel/signal32.c48
-rw-r--r--arch/sparc/kernel/signal_32.c17
-rw-r--r--arch/sparc/kernel/signal_64.c7
-rw-r--r--arch/sparc/kernel/syscalls.S6
-rw-r--r--arch/sparc/kernel/systbls_64.S2
8 files changed, 11 insertions, 84 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 89dde2f0653a..3274f5dc8deb 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -42,6 +42,7 @@ config SPARC
42 select GENERIC_STRNLEN_USER 42 select GENERIC_STRNLEN_USER
43 select MODULES_USE_ELF_RELA 43 select MODULES_USE_ELF_RELA
44 select ODD_RT_SIGACTION 44 select ODD_RT_SIGACTION
45 select GENERIC_SIGALTSTACK
45 46
46config SPARC32 47config SPARC32
47 def_bool !64BIT 48 def_bool !64BIT
diff --git a/arch/sparc/include/asm/compat_signal.h b/arch/sparc/include/asm/compat_signal.h
index b759eab9b51c..9ed1f128b4d1 100644
--- a/arch/sparc/include/asm/compat_signal.h
+++ b/arch/sparc/include/asm/compat_signal.h
@@ -18,12 +18,6 @@ struct __old_sigaction32 {
18 unsigned int sa_flags; 18 unsigned int sa_flags;
19 unsigned sa_restorer; /* not used by Linux/SPARC yet */ 19 unsigned sa_restorer; /* not used by Linux/SPARC yet */
20}; 20};
21
22typedef struct sigaltstack32 {
23 u32 ss_sp;
24 int ss_flags;
25 compat_size_t ss_size;
26} stack_t32;
27#endif 21#endif
28 22
29#endif /* !(_COMPAT_SIGNAL_H) */ 23#endif /* !(_COMPAT_SIGNAL_H) */
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 21fd1a8f47d2..e2a030045089 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -820,14 +820,6 @@ sys_sparc_pipe:
820 mov %l5, %o7 820 mov %l5, %o7
821 821
822 .align 4 822 .align 4
823 .globl sys_sigaltstack
824sys_sigaltstack:
825 mov %o7, %l5
826 mov %fp, %o2
827 call do_sigaltstack
828 mov %l5, %o7
829
830 .align 4
831 .globl sys_sigstack 823 .globl sys_sigstack
832sys_sigstack: 824sys_sigstack:
833 mov %o7, %l5 825 mov %o7, %l5
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 53e48f721ce3..9d9eb91d0de1 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -61,7 +61,7 @@ struct rt_signal_frame32 {
61 compat_sigset_t mask; 61 compat_sigset_t mask;
62 /* __siginfo_fpu_t * */ u32 fpu_save; 62 /* __siginfo_fpu_t * */ u32 fpu_save;
63 unsigned int insns[2]; 63 unsigned int insns[2];
64 stack_t32 stack; 64 compat_stack_t stack;
65 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ 65 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
66 /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ 66 /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
67 siginfo_extra_v8plus_t v8plus; 67 siginfo_extra_v8plus_t v8plus;
@@ -230,13 +230,11 @@ segv:
230asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) 230asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
231{ 231{
232 struct rt_signal_frame32 __user *sf; 232 struct rt_signal_frame32 __user *sf;
233 unsigned int psr, pc, npc, u_ss_sp; 233 unsigned int psr, pc, npc;
234 compat_uptr_t fpu_save; 234 compat_uptr_t fpu_save;
235 compat_uptr_t rwin_save; 235 compat_uptr_t rwin_save;
236 mm_segment_t old_fs;
237 sigset_t set; 236 sigset_t set;
238 compat_sigset_t seta; 237 compat_sigset_t seta;
239 stack_t st;
240 int err, i; 238 int err, i;
241 239
242 /* Always make any pending restarted system calls return -EINTR */ 240 /* Always make any pending restarted system calls return -EINTR */
@@ -295,20 +293,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
295 if (!err && fpu_save) 293 if (!err && fpu_save)
296 err |= restore_fpu_state(regs, compat_ptr(fpu_save)); 294 err |= restore_fpu_state(regs, compat_ptr(fpu_save));
297 err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); 295 err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
298 err |= __get_user(u_ss_sp, &sf->stack.ss_sp); 296 err |= compat_restore_altstack(&sf->stack);
299 st.ss_sp = compat_ptr(u_ss_sp);
300 err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
301 err |= __get_user(st.ss_size, &sf->stack.ss_size);
302 if (err) 297 if (err)
303 goto segv; 298 goto segv;
304 299
305 /* It is more difficult to avoid calling this function than to
306 call it and ignore errors. */
307 old_fs = get_fs();
308 set_fs(KERNEL_DS);
309 do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
310 set_fs(old_fs);
311
312 err |= __get_user(rwin_save, &sf->rwin_save); 300 err |= __get_user(rwin_save, &sf->rwin_save);
313 if (!err && rwin_save) { 301 if (!err && rwin_save) {
314 if (restore_rwin_state(compat_ptr(rwin_save))) 302 if (restore_rwin_state(compat_ptr(rwin_save)))
@@ -642,9 +630,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
642 err |= copy_siginfo_to_user32(&sf->info, info); 630 err |= copy_siginfo_to_user32(&sf->info, info);
643 631
644 /* Setup sigaltstack */ 632 /* Setup sigaltstack */
645 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); 633 err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
646 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
647 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
648 634
649 switch (_NSIG_WORDS) { 635 switch (_NSIG_WORDS) {
650 case 4: seta.sig[7] = (oldset->sig[3] >> 32); 636 case 4: seta.sig[7] = (oldset->sig[3] >> 32);
@@ -856,29 +842,3 @@ asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
856out: 842out:
857 return ret; 843 return ret;
858} 844}
859
860asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
861{
862 stack_t uss, uoss;
863 u32 u_ss_sp = 0;
864 int ret;
865 mm_segment_t old_fs;
866 stack_t32 __user *uss32 = compat_ptr(ussa);
867 stack_t32 __user *uoss32 = compat_ptr(uossa);
868
869 if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
870 __get_user(uss.ss_flags, &uss32->ss_flags) ||
871 __get_user(uss.ss_size, &uss32->ss_size)))
872 return -EFAULT;
873 uss.ss_sp = compat_ptr(u_ss_sp);
874 old_fs = get_fs();
875 set_fs(KERNEL_DS);
876 ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
877 uossa ? (stack_t __user *) &uoss : NULL, sp);
878 set_fs(old_fs);
879 if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
880 __put_user(uoss.ss_flags, &uoss32->ss_flags) ||
881 __put_user(uoss.ss_size, &uoss32->ss_size)))
882 return -EFAULT;
883 return ret;
884}
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 68f9c8650af4..7391fa89651f 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -141,9 +141,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
141 unsigned int psr, pc, npc; 141 unsigned int psr, pc, npc;
142 __siginfo_fpu_t __user *fpu_save; 142 __siginfo_fpu_t __user *fpu_save;
143 __siginfo_rwin_t __user *rwin_save; 143 __siginfo_rwin_t __user *rwin_save;
144 mm_segment_t old_fs;
145 sigset_t set; 144 sigset_t set;
146 stack_t st;
147 int err; 145 int err;
148 146
149 synchronize_user_stack(); 147 synchronize_user_stack();
@@ -171,8 +169,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
171 if (!err && fpu_save) 169 if (!err && fpu_save)
172 err |= restore_fpu_state(regs, fpu_save); 170 err |= restore_fpu_state(regs, fpu_save);
173 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); 171 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
174 172 err |= restore_altstack(&sf->stack);
175 err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t));
176 173
177 if (err) 174 if (err)
178 goto segv; 175 goto segv;
@@ -180,14 +177,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
180 regs->pc = pc; 177 regs->pc = pc;
181 regs->npc = npc; 178 regs->npc = npc;
182 179
183 /* It is more difficult to avoid calling this function than to
184 * call it and ignore errors.
185 */
186 old_fs = get_fs();
187 set_fs(KERNEL_DS);
188 do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
189 set_fs(old_fs);
190
191 err |= __get_user(rwin_save, &sf->rwin_save); 180 err |= __get_user(rwin_save, &sf->rwin_save);
192 if (!err && rwin_save) { 181 if (!err && rwin_save) {
193 if (restore_rwin_state(rwin_save)) 182 if (restore_rwin_state(rwin_save))
@@ -391,9 +380,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
391 err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t)); 380 err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
392 381
393 /* Setup sigaltstack */ 382 /* Setup sigaltstack */
394 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); 383 err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
395 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
396 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
397 384
398 if (!wsaved) { 385 if (!wsaved) {
399 err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], 386 err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 689e1ba62809..176e0e7b8f60 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -295,7 +295,8 @@ void do_rt_sigreturn(struct pt_regs *regs)
295 err |= restore_fpu_state(regs, fpu_save); 295 err |= restore_fpu_state(regs, fpu_save);
296 296
297 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); 297 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
298 if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) 298 err |= restore_altstack(&sf->stack);
299 if (err)
299 goto segv; 300 goto segv;
300 301
301 err |= __get_user(rwin_save, &sf->rwin_save); 302 err |= __get_user(rwin_save, &sf->rwin_save);
@@ -403,9 +404,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
403 } 404 }
404 405
405 /* Setup sigaltstack */ 406 /* Setup sigaltstack */
406 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); 407 err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
407 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
408 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
409 408
410 err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); 409 err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
411 410
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index e0fed7711a94..22a1098961f5 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -25,16 +25,10 @@ sys_nis_syscall:
25sys_memory_ordering: 25sys_memory_ordering:
26 ba,pt %xcc, sparc_memory_ordering 26 ba,pt %xcc, sparc_memory_ordering
27 add %sp, PTREGS_OFF, %o1 27 add %sp, PTREGS_OFF, %o1
28sys_sigaltstack:
29 ba,pt %xcc, do_sigaltstack
30 add %i6, STACK_BIAS, %o2
31#ifdef CONFIG_COMPAT 28#ifdef CONFIG_COMPAT
32sys32_sigstack: 29sys32_sigstack:
33 ba,pt %xcc, do_sys32_sigstack 30 ba,pt %xcc, do_sys32_sigstack
34 mov %i6, %o2 31 mov %i6, %o2
35sys32_sigaltstack:
36 ba,pt %xcc, do_sys32_sigaltstack
37 mov %i6, %o2
38#endif 32#endif
39 .align 32 33 .align 32
40#ifdef CONFIG_COMPAT 34#ifdef CONFIG_COMPAT
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 1009ecb92678..83ec8d467083 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -23,7 +23,7 @@ sys_call_table32:
23/*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod 23/*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
24/*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek 24/*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek
25/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 25/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
26/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause 26/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, compat_sys_sigaltstack, sys_pause
27/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice 27/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
28 .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile 28 .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile
29/*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid 29/*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid