aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/signal_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/signal_32.c')
-rw-r--r--arch/sparc/kernel/signal_32.c175
1 files changed, 61 insertions, 114 deletions
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 68f9c8650af4..7d5d8e1f8415 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -59,18 +59,6 @@ struct rt_signal_frame {
59#define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7))) 59#define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
60#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) 60#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
61 61
62static int _sigpause_common(old_sigset_t set)
63{
64 sigset_t blocked;
65 siginitset(&blocked, set);
66 return sigsuspend(&blocked);
67}
68
69asmlinkage int sys_sigsuspend(old_sigset_t set)
70{
71 return _sigpause_common(set);
72}
73
74asmlinkage void do_sigreturn(struct pt_regs *regs) 62asmlinkage void do_sigreturn(struct pt_regs *regs)
75{ 63{
76 struct signal_frame __user *sf; 64 struct signal_frame __user *sf;
@@ -141,9 +129,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
141 unsigned int psr, pc, npc; 129 unsigned int psr, pc, npc;
142 __siginfo_fpu_t __user *fpu_save; 130 __siginfo_fpu_t __user *fpu_save;
143 __siginfo_rwin_t __user *rwin_save; 131 __siginfo_rwin_t __user *rwin_save;
144 mm_segment_t old_fs;
145 sigset_t set; 132 sigset_t set;
146 stack_t st;
147 int err; 133 int err;
148 134
149 synchronize_user_stack(); 135 synchronize_user_stack();
@@ -171,8 +157,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
171 if (!err && fpu_save) 157 if (!err && fpu_save)
172 err |= restore_fpu_state(regs, fpu_save); 158 err |= restore_fpu_state(regs, fpu_save);
173 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); 159 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
174 160 err |= restore_altstack(&sf->stack);
175 err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t));
176 161
177 if (err) 162 if (err)
178 goto segv; 163 goto segv;
@@ -180,14 +165,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
180 regs->pc = pc; 165 regs->pc = pc;
181 regs->npc = npc; 166 regs->npc = npc;
182 167
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); 168 err |= __get_user(rwin_save, &sf->rwin_save);
192 if (!err && rwin_save) { 169 if (!err && rwin_save) {
193 if (restore_rwin_state(rwin_save)) 170 if (restore_rwin_state(rwin_save))
@@ -209,7 +186,7 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen)
209 return 0; 186 return 0;
210} 187}
211 188
212static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) 189static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
213{ 190{
214 unsigned long sp = regs->u_regs[UREG_FP]; 191 unsigned long sp = regs->u_regs[UREG_FP];
215 192
@@ -221,12 +198,7 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
221 return (void __user *) -1L; 198 return (void __user *) -1L;
222 199
223 /* This is the X/Open sanctioned signal stack switching. */ 200 /* This is the X/Open sanctioned signal stack switching. */
224 if (sa->sa_flags & SA_ONSTACK) { 201 sp = sigsp(sp, ksig) - framesize;
225 if (sas_ss_flags(sp) == 0)
226 sp = current->sas_ss_sp + current->sas_ss_size;
227 }
228
229 sp -= framesize;
230 202
231 /* Always align the stack frame. This handles two cases. First, 203 /* Always align the stack frame. This handles two cases. First,
232 * sigaltstack need not be mindful of platform specific stack 204 * sigaltstack need not be mindful of platform specific stack
@@ -239,8 +211,8 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
239 return (void __user *) sp; 211 return (void __user *) sp;
240} 212}
241 213
242static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, 214static int setup_frame(struct ksignal *ksig, struct pt_regs *regs,
243 int signo, sigset_t *oldset) 215 sigset_t *oldset)
244{ 216{
245 struct signal_frame __user *sf; 217 struct signal_frame __user *sf;
246 int sigframe_size, err, wsaved; 218 int sigframe_size, err, wsaved;
@@ -258,10 +230,12 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
258 sigframe_size += sizeof(__siginfo_rwin_t); 230 sigframe_size += sizeof(__siginfo_rwin_t);
259 231
260 sf = (struct signal_frame __user *) 232 sf = (struct signal_frame __user *)
261 get_sigframe(&ka->sa, regs, sigframe_size); 233 get_sigframe(ksig, regs, sigframe_size);
262 234
263 if (invalid_frame_pointer(sf, sigframe_size)) 235 if (invalid_frame_pointer(sf, sigframe_size)) {
264 goto sigill_and_return; 236 do_exit(SIGILL);
237 return -EINVAL;
238 }
265 239
266 tail = sf + 1; 240 tail = sf + 1;
267 241
@@ -300,21 +274,21 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
300 err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); 274 err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
301 } 275 }
302 if (err) 276 if (err)
303 goto sigsegv; 277 return err;
304 278
305 /* 3. signal handler back-trampoline and parameters */ 279 /* 3. signal handler back-trampoline and parameters */
306 regs->u_regs[UREG_FP] = (unsigned long) sf; 280 regs->u_regs[UREG_FP] = (unsigned long) sf;
307 regs->u_regs[UREG_I0] = signo; 281 regs->u_regs[UREG_I0] = ksig->sig;
308 regs->u_regs[UREG_I1] = (unsigned long) &sf->info; 282 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
309 regs->u_regs[UREG_I2] = (unsigned long) &sf->info; 283 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
310 284
311 /* 4. signal handler */ 285 /* 4. signal handler */
312 regs->pc = (unsigned long) ka->sa.sa_handler; 286 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
313 regs->npc = (regs->pc + 4); 287 regs->npc = (regs->pc + 4);
314 288
315 /* 5. return to kernel instructions */ 289 /* 5. return to kernel instructions */
316 if (ka->ka_restorer) 290 if (ksig->ka.ka_restorer)
317 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; 291 regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
318 else { 292 else {
319 regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); 293 regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
320 294
@@ -324,24 +298,16 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
324 /* t 0x10 */ 298 /* t 0x10 */
325 err |= __put_user(0x91d02010, &sf->insns[1]); 299 err |= __put_user(0x91d02010, &sf->insns[1]);
326 if (err) 300 if (err)
327 goto sigsegv; 301 return err;
328 302
329 /* Flush instruction space. */ 303 /* Flush instruction space. */
330 flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); 304 flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
331 } 305 }
332 return 0; 306 return 0;
333
334sigill_and_return:
335 do_exit(SIGILL);
336 return -EINVAL;
337
338sigsegv:
339 force_sigsegv(signo, current);
340 return -EFAULT;
341} 307}
342 308
343static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, 309static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs,
344 int signo, sigset_t *oldset, siginfo_t *info) 310 sigset_t *oldset)
345{ 311{
346 struct rt_signal_frame __user *sf; 312 struct rt_signal_frame __user *sf;
347 int sigframe_size, wsaved; 313 int sigframe_size, wsaved;
@@ -357,9 +323,11 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
357 if (wsaved) 323 if (wsaved)
358 sigframe_size += sizeof(__siginfo_rwin_t); 324 sigframe_size += sizeof(__siginfo_rwin_t);
359 sf = (struct rt_signal_frame __user *) 325 sf = (struct rt_signal_frame __user *)
360 get_sigframe(&ka->sa, regs, sigframe_size); 326 get_sigframe(ksig, regs, sigframe_size);
361 if (invalid_frame_pointer(sf, sigframe_size)) 327 if (invalid_frame_pointer(sf, sigframe_size)) {
362 goto sigill; 328 do_exit(SIGILL);
329 return -EINVAL;
330 }
363 331
364 tail = sf + 1; 332 tail = sf + 1;
365 err = __put_user(regs->pc, &sf->regs.pc); 333 err = __put_user(regs->pc, &sf->regs.pc);
@@ -391,9 +359,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)); 359 err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
392 360
393 /* Setup sigaltstack */ 361 /* Setup sigaltstack */
394 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); 362 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 363
398 if (!wsaved) { 364 if (!wsaved) {
399 err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], 365 err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
@@ -405,21 +371,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
405 err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); 371 err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
406 } 372 }
407 373
408 err |= copy_siginfo_to_user(&sf->info, info); 374 err |= copy_siginfo_to_user(&sf->info, &ksig->info);
409 375
410 if (err) 376 if (err)
411 goto sigsegv; 377 return err;
412 378
413 regs->u_regs[UREG_FP] = (unsigned long) sf; 379 regs->u_regs[UREG_FP] = (unsigned long) sf;
414 regs->u_regs[UREG_I0] = signo; 380 regs->u_regs[UREG_I0] = ksig->sig;
415 regs->u_regs[UREG_I1] = (unsigned long) &sf->info; 381 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
416 regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; 382 regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
417 383
418 regs->pc = (unsigned long) ka->sa.sa_handler; 384 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
419 regs->npc = (regs->pc + 4); 385 regs->npc = (regs->pc + 4);
420 386
421 if (ka->ka_restorer) 387 if (ksig->ka.ka_restorer)
422 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; 388 regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
423 else { 389 else {
424 regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); 390 regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
425 391
@@ -429,38 +395,25 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
429 /* t 0x10 */ 395 /* t 0x10 */
430 err |= __put_user(0x91d02010, &sf->insns[1]); 396 err |= __put_user(0x91d02010, &sf->insns[1]);
431 if (err) 397 if (err)
432 goto sigsegv; 398 return err;
433 399
434 /* Flush instruction space. */ 400 /* Flush instruction space. */
435 flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); 401 flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
436 } 402 }
437 return 0; 403 return 0;
438
439sigill:
440 do_exit(SIGILL);
441 return -EINVAL;
442
443sigsegv:
444 force_sigsegv(signo, current);
445 return -EFAULT;
446} 404}
447 405
448static inline void 406static inline void
449handle_signal(unsigned long signr, struct k_sigaction *ka, 407handle_signal(struct ksignal *ksig, struct pt_regs *regs)
450 siginfo_t *info, struct pt_regs *regs)
451{ 408{
452 sigset_t *oldset = sigmask_to_save(); 409 sigset_t *oldset = sigmask_to_save();
453 int err; 410 int err;
454 411
455 if (ka->sa.sa_flags & SA_SIGINFO) 412 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
456 err = setup_rt_frame(ka, regs, signr, oldset, info); 413 err = setup_rt_frame(ksig, regs, oldset);
457 else 414 else
458 err = setup_frame(ka, regs, signr, oldset); 415 err = setup_frame(ksig, regs, oldset);
459 416 signal_setup_done(err, ksig, 0);
460 if (err)
461 return;
462
463 signal_delivered(signr, info, ka, regs, 0);
464} 417}
465 418
466static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, 419static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -490,10 +443,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
490 */ 443 */
491static void do_signal(struct pt_regs *regs, unsigned long orig_i0) 444static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
492{ 445{
493 struct k_sigaction ka; 446 struct ksignal ksig;
494 int restart_syscall; 447 int restart_syscall;
495 siginfo_t info; 448 bool has_handler;
496 int signr;
497 449
498 /* It's a lot of work and synchronization to add a new ptrace 450 /* It's a lot of work and synchronization to add a new ptrace
499 * register for GDB to save and restore in order to get 451 * register for GDB to save and restore in order to get
@@ -516,7 +468,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
516 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) 468 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
517 regs->u_regs[UREG_G6] = orig_i0; 469 regs->u_regs[UREG_G6] = orig_i0;
518 470
519 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 471 has_handler = get_signal(&ksig);
520 472
521 /* If the debugger messes with the program counter, it clears 473 /* If the debugger messes with the program counter, it clears
522 * the software "in syscall" bit, directing us to not perform 474 * the software "in syscall" bit, directing us to not perform
@@ -528,35 +480,30 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
528 orig_i0 = regs->u_regs[UREG_G6]; 480 orig_i0 = regs->u_regs[UREG_G6];
529 } 481 }
530 482
531 483 if (has_handler) {
532 if (signr > 0) {
533 if (restart_syscall) 484 if (restart_syscall)
534 syscall_restart(orig_i0, regs, &ka.sa); 485 syscall_restart(orig_i0, regs, &ksig.ka.sa);
535 handle_signal(signr, &ka, &info, regs); 486 handle_signal(&ksig, regs);
536 return; 487 } else {
537 } 488 if (restart_syscall) {
538 if (restart_syscall && 489 switch (regs->u_regs[UREG_I0]) {
539 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 490 case ERESTARTNOHAND:
540 regs->u_regs[UREG_I0] == ERESTARTSYS || 491 case ERESTARTSYS:
541 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { 492 case ERESTARTNOINTR:
542 /* replay the system call when we are done */ 493 /* replay the system call when we are done */
543 regs->u_regs[UREG_I0] = orig_i0; 494 regs->u_regs[UREG_I0] = orig_i0;
544 regs->pc -= 4; 495 regs->pc -= 4;
545 regs->npc -= 4; 496 regs->npc -= 4;
546 pt_regs_clear_syscall(regs); 497 pt_regs_clear_syscall(regs);
547 } 498 case ERESTART_RESTARTBLOCK:
548 if (restart_syscall && 499 regs->u_regs[UREG_G1] = __NR_restart_syscall;
549 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { 500 regs->pc -= 4;
550 regs->u_regs[UREG_G1] = __NR_restart_syscall; 501 regs->npc -= 4;
551 regs->pc -= 4; 502 pt_regs_clear_syscall(regs);
552 regs->npc -= 4; 503 }
553 pt_regs_clear_syscall(regs); 504 }
505 restore_saved_sigmask();
554 } 506 }
555
556 /* if there's no signal to deliver, we just put the saved sigmask
557 * back
558 */
559 restore_saved_sigmask();
560} 507}
561 508
562void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, 509void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,