aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa
diff options
context:
space:
mode:
Diffstat (limited to 'arch/xtensa')
-rw-r--r--arch/xtensa/include/asm/processor.h1
-rw-r--r--arch/xtensa/kernel/signal.c43
2 files changed, 17 insertions, 27 deletions
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index abb59708a3b7..b61bdf0eea25 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -182,6 +182,7 @@ extern unsigned long get_wchan(struct task_struct *p);
182#define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1]) 182#define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1])
183 183
184#define cpu_relax() barrier() 184#define cpu_relax() barrier()
185#define cpu_relax_lowlatency() cpu_relax()
185 186
186/* Special register access. */ 187/* Special register access. */
187 188
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index 98b67d5f1514..4612321c73cc 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -331,17 +331,17 @@ gen_return_code(unsigned char *codemem)
331} 331}
332 332
333 333
334static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 334static int setup_frame(struct ksignal *ksig, sigset_t *set,
335 sigset_t *set, struct pt_regs *regs) 335 struct pt_regs *regs)
336{ 336{
337 struct rt_sigframe *frame; 337 struct rt_sigframe *frame;
338 int err = 0; 338 int err = 0, sig = ksig->sig;
339 int signal; 339 int signal;
340 unsigned long sp, ra, tp; 340 unsigned long sp, ra, tp;
341 341
342 sp = regs->areg[1]; 342 sp = regs->areg[1];
343 343
344 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) { 344 if ((ksig->ka.sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
345 sp = current->sas_ss_sp + current->sas_ss_size; 345 sp = current->sas_ss_sp + current->sas_ss_size;
346 } 346 }
347 347
@@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
351 panic ("Double exception sys_sigreturn\n"); 351 panic ("Double exception sys_sigreturn\n");
352 352
353 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) { 353 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
354 goto give_sigsegv; 354 return -EFAULT;
355 } 355 }
356 356
357 signal = current_thread_info()->exec_domain 357 signal = current_thread_info()->exec_domain
@@ -360,8 +360,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
360 ? current_thread_info()->exec_domain->signal_invmap[sig] 360 ? current_thread_info()->exec_domain->signal_invmap[sig]
361 : sig; 361 : sig;
362 362
363 if (ka->sa.sa_flags & SA_SIGINFO) { 363 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
364 err |= copy_siginfo_to_user(&frame->info, info); 364 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
365 } 365 }
366 366
367 /* Create the user context. */ 367 /* Create the user context. */
@@ -372,8 +372,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
372 err |= setup_sigcontext(frame, regs); 372 err |= setup_sigcontext(frame, regs);
373 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 373 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
374 374
375 if (ka->sa.sa_flags & SA_RESTORER) { 375 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
376 ra = (unsigned long)ka->sa.sa_restorer; 376 ra = (unsigned long)ksig->ka.sa.sa_restorer;
377 } else { 377 } else {
378 378
379 /* Create sys_rt_sigreturn syscall in stack frame */ 379 /* Create sys_rt_sigreturn syscall in stack frame */
@@ -381,7 +381,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
381 err |= gen_return_code(frame->retcode); 381 err |= gen_return_code(frame->retcode);
382 382
383 if (err) { 383 if (err) {
384 goto give_sigsegv; 384 return -EFAULT;
385 } 385 }
386 ra = (unsigned long) frame->retcode; 386 ra = (unsigned long) frame->retcode;
387 } 387 }
@@ -393,7 +393,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
393 393
394 /* Set up registers for signal handler; preserve the threadptr */ 394 /* Set up registers for signal handler; preserve the threadptr */
395 tp = regs->threadptr; 395 tp = regs->threadptr;
396 start_thread(regs, (unsigned long) ka->sa.sa_handler, 396 start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler,
397 (unsigned long) frame); 397 (unsigned long) frame);
398 398
399 /* Set up a stack frame for a call4 399 /* Set up a stack frame for a call4
@@ -416,10 +416,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
416#endif 416#endif
417 417
418 return 0; 418 return 0;
419
420give_sigsegv:
421 force_sigsegv(sig, current);
422 return -EFAULT;
423} 419}
424 420
425/* 421/*
@@ -433,15 +429,11 @@ give_sigsegv:
433 */ 429 */
434static void do_signal(struct pt_regs *regs) 430static void do_signal(struct pt_regs *regs)
435{ 431{
436 siginfo_t info; 432 struct ksignal ksig;
437 int signr;
438 struct k_sigaction ka;
439 433
440 task_pt_regs(current)->icountlevel = 0; 434 task_pt_regs(current)->icountlevel = 0;
441 435
442 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 436 if (get_signal(&ksig)) {
443
444 if (signr > 0) {
445 int ret; 437 int ret;
446 438
447 /* Are we from a system call? */ 439 /* Are we from a system call? */
@@ -457,7 +449,7 @@ static void do_signal(struct pt_regs *regs)
457 break; 449 break;
458 450
459 case -ERESTARTSYS: 451 case -ERESTARTSYS:
460 if (!(ka.sa.sa_flags & SA_RESTART)) { 452 if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
461 regs->areg[2] = -EINTR; 453 regs->areg[2] = -EINTR;
462 break; 454 break;
463 } 455 }
@@ -476,11 +468,8 @@ static void do_signal(struct pt_regs *regs)
476 468
477 /* Whee! Actually deliver the signal. */ 469 /* Whee! Actually deliver the signal. */
478 /* Set up the stack frame */ 470 /* Set up the stack frame */
479 ret = setup_frame(signr, &ka, &info, sigmask_to_save(), regs); 471 ret = setup_frame(&ksig, sigmask_to_save(), regs);
480 if (ret) 472 signal_setup_done(ret, &ksig, 0);
481 return;
482
483 signal_delivered(signr, &info, &ka, regs, 0);
484 if (current->ptrace & PT_SINGLESTEP) 473 if (current->ptrace & PT_SINGLESTEP)
485 task_pt_regs(current)->icountlevel = 1; 474 task_pt_regs(current)->icountlevel = 1;
486 475