aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-12-23 03:13:40 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2013-02-03 18:32:24 -0500
commitea536ad4f231a0055792d9b144715605cbd670c1 (patch)
tree31c7cd55f356cc80ba28b6e989e99af27fd2c567 /arch/mips
parentc6489c147de592af4d0d1c5263e7b4f0e8e7d100 (diff)
mips: switch to generic sigaltstack
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/include/asm/compat.h8
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/signal.c21
-rw-r--r--arch/mips/kernel/signal32.c75
-rw-r--r--arch/mips/kernel/signal_n32.c38
7 files changed, 20 insertions, 127 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2ac626ab9d43..a8a41e091d04 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -41,6 +41,7 @@ config MIPS
41 select HAVE_MOD_ARCH_SPECIFIC 41 select HAVE_MOD_ARCH_SPECIFIC
42 select MODULES_USE_ELF_REL if MODULES 42 select MODULES_USE_ELF_REL if MODULES
43 select MODULES_USE_ELF_RELA if MODULES && 64BIT 43 select MODULES_USE_ELF_RELA if MODULES && 64BIT
44 select GENERIC_SIGALTSTACK
44 45
45menu "Machine selection" 46menu "Machine selection"
46 47
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index 3c5d1464b7bd..ebaae9649f8a 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -288,6 +288,14 @@ struct compat_shmid64_ds {
288 compat_ulong_t __unused2; 288 compat_ulong_t __unused2;
289}; 289};
290 290
291/* MIPS has unusual order of fields in stack_t */
292typedef struct compat_sigaltstack {
293 compat_uptr_t ss_sp;
294 compat_size_t ss_size;
295 int ss_flags;
296} compat_stack_t;
297#define compat_sigaltstack compat_sigaltstack
298
291static inline int is_compat_task(void) 299static inline int is_compat_task(void)
292{ 300{
293 return test_thread_flag(TIF_32BIT_ADDR); 301 return test_thread_flag(TIF_32BIT_ADDR);
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index c29ac197f446..7388e25984b2 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -233,7 +233,7 @@ EXPORT(sysn32_call_table)
233 PTR compat_sys_rt_sigtimedwait 233 PTR compat_sys_rt_sigtimedwait
234 PTR sys_32_rt_sigqueueinfo 234 PTR sys_32_rt_sigqueueinfo
235 PTR sysn32_rt_sigsuspend 235 PTR sysn32_rt_sigsuspend
236 PTR sys32_sigaltstack 236 PTR compat_sys_sigaltstack
237 PTR compat_sys_utime /* 6130 */ 237 PTR compat_sys_utime /* 6130 */
238 PTR sys_mknod 238 PTR sys_mknod
239 PTR sys_32_personality 239 PTR sys_32_personality
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index cf3e75e46650..07fcd818ad3a 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -398,7 +398,7 @@ sys_call_table:
398 PTR sys_getcwd 398 PTR sys_getcwd
399 PTR sys_capget 399 PTR sys_capget
400 PTR sys_capset /* 4205 */ 400 PTR sys_capset /* 4205 */
401 PTR sys32_sigaltstack 401 PTR compat_sys_sigaltstack
402 PTR sys_32_sendfile 402 PTR sys_32_sendfile
403 PTR sys_ni_syscall 403 PTR sys_ni_syscall
404 PTR sys_ni_syscall 404 PTR sys_ni_syscall
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 4d790d1f03d6..eab30865b2bd 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -313,15 +313,6 @@ SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act,
313} 313}
314#endif 314#endif
315 315
316asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
317{
318 const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
319 stack_t __user *uoss = (stack_t __user *) regs.regs[5];
320 unsigned long usp = regs.regs[29];
321
322 return do_sigaltstack(uss, uoss, usp);
323}
324
325#ifdef CONFIG_TRAD_SIGNALS 316#ifdef CONFIG_TRAD_SIGNALS
326asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs) 317asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
327{ 318{
@@ -378,9 +369,8 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
378 else if (sig) 369 else if (sig)
379 force_sig(sig, current); 370 force_sig(sig, current);
380 371
381 /* It is more difficult to avoid calling this function than to 372 if (restore_altstack(&frame->rs_uc.uc_stack))
382 call it and ignore errors. */ 373 goto badframe;
383 do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs.regs[29]);
384 374
385 /* 375 /*
386 * Don't let your children do this ... 376 * Don't let your children do this ...
@@ -457,12 +447,7 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
457 /* Create the ucontext. */ 447 /* Create the ucontext. */
458 err |= __put_user(0, &frame->rs_uc.uc_flags); 448 err |= __put_user(0, &frame->rs_uc.uc_flags);
459 err |= __put_user(NULL, &frame->rs_uc.uc_link); 449 err |= __put_user(NULL, &frame->rs_uc.uc_link);
460 err |= __put_user((void __user *)current->sas_ss_sp, 450 err |= __save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
461 &frame->rs_uc.uc_stack.ss_sp);
462 err |= __put_user(sas_ss_flags(regs->regs[29]),
463 &frame->rs_uc.uc_stack.ss_flags);
464 err |= __put_user(current->sas_ss_size,
465 &frame->rs_uc.uc_stack.ss_size);
466 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); 451 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
467 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); 452 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
468 453
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index da1b56a39ac7..c51e5df4297b 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -61,17 +61,10 @@ struct sigaction32 {
61 compat_sigset_t sa_mask; 61 compat_sigset_t sa_mask;
62}; 62};
63 63
64/* IRIX compatible stack_t */
65typedef struct sigaltstack32 {
66 s32 ss_sp;
67 compat_size_t ss_size;
68 int ss_flags;
69} stack32_t;
70
71struct ucontext32 { 64struct ucontext32 {
72 u32 uc_flags; 65 u32 uc_flags;
73 s32 uc_link; 66 s32 uc_link;
74 stack32_t uc_stack; 67 compat_stack_t uc_stack;
75 struct sigcontext32 uc_mcontext; 68 struct sigcontext32 uc_mcontext;
76 compat_sigset_t uc_sigmask; /* mask last for extensibility */ 69 compat_sigset_t uc_sigmask; /* mask last for extensibility */
77}; 70};
@@ -350,45 +343,6 @@ SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
350 return ret; 343 return ret;
351} 344}
352 345
353asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
354{
355 const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
356 stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
357 unsigned long usp = regs.regs[29];
358 stack_t kss, koss;
359 int ret, err = 0;
360 mm_segment_t old_fs = get_fs();
361 s32 sp;
362
363 if (uss) {
364 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
365 return -EFAULT;
366 err |= __get_user(sp, &uss->ss_sp);
367 kss.ss_sp = (void __user *) (long) sp;
368 err |= __get_user(kss.ss_size, &uss->ss_size);
369 err |= __get_user(kss.ss_flags, &uss->ss_flags);
370 if (err)
371 return -EFAULT;
372 }
373
374 set_fs(KERNEL_DS);
375 ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
376 uoss ? (stack_t __user *)&koss : NULL, usp);
377 set_fs(old_fs);
378
379 if (!ret && uoss) {
380 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
381 return -EFAULT;
382 sp = (int) (unsigned long) koss.ss_sp;
383 err |= __put_user(sp, &uoss->ss_sp);
384 err |= __put_user(koss.ss_size, &uoss->ss_size);
385 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
386 if (err)
387 return -EFAULT;
388 }
389 return ret;
390}
391
392int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 346int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
393{ 347{
394 int err; 348 int err;
@@ -490,10 +444,7 @@ badframe:
490asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) 444asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
491{ 445{
492 struct rt_sigframe32 __user *frame; 446 struct rt_sigframe32 __user *frame;
493 mm_segment_t old_fs;
494 sigset_t set; 447 sigset_t set;
495 stack_t st;
496 s32 sp;
497 int sig; 448 int sig;
498 449
499 frame = (struct rt_sigframe32 __user *) regs.regs[29]; 450 frame = (struct rt_sigframe32 __user *) regs.regs[29];
@@ -510,22 +461,9 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
510 else if (sig) 461 else if (sig)
511 force_sig(sig, current); 462 force_sig(sig, current);
512 463
513 /* The ucontext contains a stack32_t, so we must convert! */ 464 if (compat_restore_altstack(&frame->rs_uc.uc_stack))
514 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
515 goto badframe;
516 st.ss_sp = (void __user *)(long) sp;
517 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
518 goto badframe;
519 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
520 goto badframe; 465 goto badframe;
521 466
522 /* It is more difficult to avoid calling this function than to
523 call it and ignore errors. */
524 old_fs = get_fs();
525 set_fs(KERNEL_DS);
526 do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
527 set_fs(old_fs);
528
529 /* 467 /*
530 * Don't let your children do this ... 468 * Don't let your children do this ...
531 */ 469 */
@@ -590,7 +528,6 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
590{ 528{
591 struct rt_sigframe32 __user *frame; 529 struct rt_sigframe32 __user *frame;
592 int err = 0; 530 int err = 0;
593 s32 sp;
594 531
595 frame = get_sigframe(ka, regs, sizeof(*frame)); 532 frame = get_sigframe(ka, regs, sizeof(*frame));
596 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 533 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
@@ -602,13 +539,7 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
602 /* Create the ucontext. */ 539 /* Create the ucontext. */
603 err |= __put_user(0, &frame->rs_uc.uc_flags); 540 err |= __put_user(0, &frame->rs_uc.uc_flags);
604 err |= __put_user(0, &frame->rs_uc.uc_link); 541 err |= __put_user(0, &frame->rs_uc.uc_link);
605 sp = (int) (long) current->sas_ss_sp; 542 err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
606 err |= __put_user(sp,
607 &frame->rs_uc.uc_stack.ss_sp);
608 err |= __put_user(sas_ss_flags(regs->regs[29]),
609 &frame->rs_uc.uc_stack.ss_flags);
610 err |= __put_user(current->sas_ss_size,
611 &frame->rs_uc.uc_stack.ss_size);
612 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext); 543 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
613 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); 544 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
614 545
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 3574c145511b..e62e2bc63a81 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -50,18 +50,10 @@
50extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); 50extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
51extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); 51extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
52 52
53
54/* IRIX compatible stack_t */
55typedef struct sigaltstack32 {
56 s32 ss_sp;
57 compat_size_t ss_size;
58 int ss_flags;
59} stack32_t;
60
61struct ucontextn32 { 53struct ucontextn32 {
62 u32 uc_flags; 54 u32 uc_flags;
63 s32 uc_link; 55 s32 uc_link;
64 stack32_t uc_stack; 56 compat_stack_t uc_stack;
65 struct sigcontext uc_mcontext; 57 struct sigcontext uc_mcontext;
66 compat_sigset_t uc_sigmask; /* mask last for extensibility */ 58 compat_sigset_t uc_sigmask; /* mask last for extensibility */
67}; 59};
@@ -97,10 +89,7 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
97asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) 89asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
98{ 90{
99 struct rt_sigframe_n32 __user *frame; 91 struct rt_sigframe_n32 __user *frame;
100 mm_segment_t old_fs;
101 sigset_t set; 92 sigset_t set;
102 stack_t st;
103 s32 sp;
104 int sig; 93 int sig;
105 94
106 frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; 95 frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
@@ -117,22 +106,8 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
117 else if (sig) 106 else if (sig)
118 force_sig(sig, current); 107 force_sig(sig, current);
119 108
120 /* The ucontext contains a stack32_t, so we must convert! */ 109 if (compat_restore_altstack(&frame->rs_uc.uc_stack))
121 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
122 goto badframe;
123 st.ss_sp = (void __user *)(long) sp;
124 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
125 goto badframe; 110 goto badframe;
126 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
127 goto badframe;
128
129 /* It is more difficult to avoid calling this function than to
130 call it and ignore errors. */
131 old_fs = get_fs();
132 set_fs(KERNEL_DS);
133 do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
134 set_fs(old_fs);
135
136 111
137 /* 112 /*
138 * Don't let your children do this ... 113 * Don't let your children do this ...
@@ -153,7 +128,6 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
153{ 128{
154 struct rt_sigframe_n32 __user *frame; 129 struct rt_sigframe_n32 __user *frame;
155 int err = 0; 130 int err = 0;
156 s32 sp;
157 131
158 frame = get_sigframe(ka, regs, sizeof(*frame)); 132 frame = get_sigframe(ka, regs, sizeof(*frame));
159 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 133 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
@@ -165,13 +139,7 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
165 /* Create the ucontext. */ 139 /* Create the ucontext. */
166 err |= __put_user(0, &frame->rs_uc.uc_flags); 140 err |= __put_user(0, &frame->rs_uc.uc_flags);
167 err |= __put_user(0, &frame->rs_uc.uc_link); 141 err |= __put_user(0, &frame->rs_uc.uc_link);
168 sp = (int) (long) current->sas_ss_sp; 142 err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
169 err |= __put_user(sp,
170 &frame->rs_uc.uc_stack.ss_sp);
171 err |= __put_user(sas_ss_flags(regs->regs[29]),
172 &frame->rs_uc.uc_stack.ss_flags);
173 err |= __put_user(current->sas_ss_size,
174 &frame->rs_uc.uc_stack.ss_size);
175 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); 143 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
176 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); 144 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
177 145