aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-04-24 02:03:06 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-05-21 23:59:47 -0400
commit969a96168091f837645a674a9f7ed1a9aaa1424b (patch)
tree30b589d6a925bf7bef1528566a03321782d711d1
parent1d5d4dbe810befe63e79b2d6cdcad2066e3b1fc4 (diff)
microblaze: handle TIF_NOTIFY_RESUME
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/microblaze/kernel/entry-nommu.S12
-rw-r--r--arch/microblaze/kernel/entry.S18
-rw-r--r--arch/microblaze/kernel/signal.c34
3 files changed, 38 insertions, 26 deletions
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index f104d276b806..ea2dd42fdc22 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -132,11 +132,11 @@ ret_from_intr:
132 beqi r11, 1f 132 beqi r11, 1f
133 bralid r15, schedule 133 bralid r15, schedule
134 nop 134 nop
1351: andi r11, r19, _TIF_SIGPENDING 1351: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
136 beqid r11, no_intr_resched 136 beqid r11, no_intr_resched
137 addk r5, r1, r0 137 addk r5, r1, r0
138 addk r7, r0, r0 138 addk r7, r0, r0
139 bralid r15, do_signal 139 bralid r15, do_notify_resume
140 addk r6, r0, r0 140 addk r6, r0, r0
141 141
142no_intr_resched: 142no_intr_resched:
@@ -292,8 +292,8 @@ ENTRY(_user_exception)
292 292
293/* 293/*
294 * Debug traps are like a system call, but entered via brki r14, 0x60 294 * Debug traps are like a system call, but entered via brki r14, 0x60
295 * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal 295 * All we need to do is send the SIGTRAP signal to current, ptrace and
296 * will handle the rest 296 * do_notify_resume will handle the rest
297 */ 297 */
298ENTRY(_debug_exception) 298ENTRY(_debug_exception)
299 swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ 299 swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
@@ -482,11 +482,11 @@ work_pending:
482 beqi r11, 1f 482 beqi r11, 1f
483 bralid r15, schedule 483 bralid r15, schedule
484 nop 484 nop
4851: andi r11, r19, _TIF_SIGPENDING 4851: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
486 beqi r11, no_work_pending 486 beqi r11, no_work_pending
487 addk r5, r1, r0 487 addk r5, r1, r0
488 addik r7, r0, 1 488 addik r7, r0, 1
489 bralid r15, do_signal 489 bralid r15, do_notify_resume
490 addk r6, r0, r0 490 addk r6, r0, r0
491 bri no_work_pending 491 bri no_work_pending
492 492
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 66e34a3bfe1b..3cee9130a392 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -430,12 +430,12 @@ C_ENTRY(ret_from_trap):
4305: /* get thread info from current task*/ 4305: /* get thread info from current task*/
431 lwi r11, CURRENT_TASK, TS_THREAD_INFO; 431 lwi r11, CURRENT_TASK, TS_THREAD_INFO;
432 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 432 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
433 andi r11, r11, _TIF_SIGPENDING; 433 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
434 beqi r11, 1f; /* Signals to handle, handle them */ 434 beqi r11, 1f; /* Signals to handle, handle them */
435 435
436 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 436 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
437 addi r7, r0, 1; /* Arg 3: int in_syscall */ 437 addi r7, r0, 1; /* Arg 3: int in_syscall */
438 bralid r15, do_signal; /* Handle any signals */ 438 bralid r15, do_notify_resume; /* Handle any signals */
439 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 439 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
440 440
441/* Finally, return to user state. */ 441/* Finally, return to user state. */
@@ -622,7 +622,7 @@ C_ENTRY(ret_from_exc):
622 /* Maybe handle a signal */ 622 /* Maybe handle a signal */
6235: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 6235: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
624 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 624 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
625 andi r11, r11, _TIF_SIGPENDING; 625 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
626 beqi r11, 1f; /* Signals to handle, handle them */ 626 beqi r11, 1f; /* Signals to handle, handle them */
627 627
628 /* 628 /*
@@ -635,10 +635,10 @@ C_ENTRY(ret_from_exc):
635 * traps), but signal handlers may want to examine or change the 635 * traps), but signal handlers may want to examine or change the
636 * complete register state. Here we save anything not saved by 636 * complete register state. Here we save anything not saved by
637 * the normal entry sequence, so that it may be safely restored 637 * the normal entry sequence, so that it may be safely restored
638 * (in a possibly modified form) after do_signal returns. */ 638 * (in a possibly modified form) after do_notify_resume returns. */
639 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 639 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
640 addi r7, r0, 0; /* Arg 3: int in_syscall */ 640 addi r7, r0, 0; /* Arg 3: int in_syscall */
641 bralid r15, do_signal; /* Handle any signals */ 641 bralid r15, do_notify_resume; /* Handle any signals */
642 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 642 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
643 643
644/* Finally, return to user state. */ 644/* Finally, return to user state. */
@@ -732,12 +732,12 @@ ret_from_irq:
732 /* Maybe handle a signal */ 732 /* Maybe handle a signal */
7335: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */ 7335: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */
734 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 734 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
735 andi r11, r11, _TIF_SIGPENDING; 735 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
736 beqid r11, no_intr_resched 736 beqid r11, no_intr_resched
737/* Handle a signal return; Pending signals should be in r18. */ 737/* Handle a signal return; Pending signals should be in r18. */
738 addi r7, r0, 0; /* Arg 3: int in_syscall */ 738 addi r7, r0, 0; /* Arg 3: int in_syscall */
739 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 739 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
740 bralid r15, do_signal; /* Handle any signals */ 740 bralid r15, do_notify_resume; /* Handle any signals */
741 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 741 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
742 742
743/* Finally, return to user state. */ 743/* Finally, return to user state. */
@@ -869,12 +869,12 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
869 /* Maybe handle a signal */ 869 /* Maybe handle a signal */
8705: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 8705: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
871 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 871 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
872 andi r11, r11, _TIF_SIGPENDING; 872 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
873 beqi r11, 1f; /* Signals to handle, handle them */ 873 beqi r11, 1f; /* Signals to handle, handle them */
874 874
875 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 875 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
876 addi r7, r0, 0; /* Arg 3: int in_syscall */ 876 addi r7, r0, 0; /* Arg 3: int in_syscall */
877 bralid r15, do_signal; /* Handle any signals */ 877 bralid r15, do_notify_resume; /* Handle any signals */
878 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 878 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
879 879
880/* Finally, return to user state. */ 880/* Finally, return to user state. */
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index fbdb02641821..449886db35a2 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -31,6 +31,7 @@
31#include <linux/personality.h> 31#include <linux/personality.h>
32#include <linux/percpu.h> 32#include <linux/percpu.h>
33#include <linux/linkage.h> 33#include <linux/linkage.h>
34#include <linux/tracehook.h>
34#include <asm/entry.h> 35#include <asm/entry.h>
35#include <asm/ucontext.h> 36#include <asm/ucontext.h>
36#include <linux/uaccess.h> 37#include <linux/uaccess.h>
@@ -42,8 +43,6 @@
42 43
43#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
44 45
45asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
46
47asmlinkage long 46asmlinkage long
48sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 47sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
49 struct pt_regs *regs) 48 struct pt_regs *regs)
@@ -340,7 +339,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
340 * the kernel can handle, and then we build all the user-level signal handling 339 * the kernel can handle, and then we build all the user-level signal handling
341 * stack-frames in one go after that. 340 * stack-frames in one go after that.
342 */ 341 */
343int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) 342static int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
344{ 343{
345 siginfo_t info; 344 siginfo_t info;
346 int signr; 345 int signr;
@@ -350,14 +349,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
350 printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1, 349 printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
351 regs->r12, current_thread_info()->flags); 350 regs->r12, current_thread_info()->flags);
352#endif 351#endif
353 /*
354 * We want the common case to go fast, which
355 * is why we may in certain cases get here from
356 * kernel mode. Just return without doing anything
357 * if so.
358 */
359 if (kernel_mode(regs))
360 return 1;
361 352
362 if (current_thread_info()->status & TS_RESTORE_SIGMASK) 353 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
363 oldset = &current->saved_sigmask; 354 oldset = &current->saved_sigmask;
@@ -397,3 +388,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
397 /* Did we come from a system call? */ 388 /* Did we come from a system call? */
398 return 0; 389 return 0;
399} 390}
391
392void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
393{
394 /*
395 * We want the common case to go fast, which
396 * is why we may in certain cases get here from
397 * kernel mode. Just return without doing anything
398 * if so.
399 */
400 if (kernel_mode(regs))
401 return;
402
403 if (test_thread_flag(TIF_SIGPENDING))
404 do_signal(regs, oldset, in_syscall);
405
406 if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
407 tracehook_notify_resume(regs);
408 if (current->replacement_session_keyring)
409 key_replace_session_keyring();
410 }
411}