microblaze: handle TIF_NOTIFY_RESUME
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 24 Apr 2012 06:03:06 +0000 (02:03 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 22 May 2012 03:59:47 +0000 (23:59 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/microblaze/kernel/entry-nommu.S
arch/microblaze/kernel/entry.S
arch/microblaze/kernel/signal.c

index f104d27..ea2dd42 100644 (file)
@@ -132,11 +132,11 @@ ret_from_intr:
        beqi    r11, 1f
        bralid  r15, schedule
        nop
-1:     andi    r11, r19, _TIF_SIGPENDING
+1:     andi    r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
        beqid   r11, no_intr_resched
        addk    r5, r1, r0
        addk    r7, r0, r0
-       bralid  r15, do_signal
+       bralid  r15, do_notify_resume
        addk    r6, r0, r0
 
 no_intr_resched:
@@ -292,8 +292,8 @@ ENTRY(_user_exception)
 
 /*
  * Debug traps are like a system call, but entered via brki r14, 0x60
- * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal
- * will handle the rest
+ * All we need to do is send the SIGTRAP signal to current, ptrace and
+ * do_notify_resume will handle the rest
  */
 ENTRY(_debug_exception)
        swi     r1, r0, PER_CPU(ENTRY_SP)       /* save the current sp */
@@ -482,11 +482,11 @@ work_pending:
        beqi    r11, 1f
        bralid  r15, schedule
        nop
-1:     andi    r11, r19, _TIF_SIGPENDING
+1:     andi    r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
        beqi    r11, no_work_pending
        addk    r5, r1, r0
        addik   r7, r0, 1
-       bralid  r15, do_signal
+       bralid  r15, do_notify_resume
        addk    r6, r0, r0
        bri     no_work_pending
 
index 66e34a3..3cee913 100644 (file)
@@ -430,12 +430,12 @@ C_ENTRY(ret_from_trap):
 5:     /* get thread info from current task*/
        lwi     r11, CURRENT_TASK, TS_THREAD_INFO;
        lwi     r11, r11, TI_FLAGS;     /* get flags in thread info */
-       andi    r11, r11, _TIF_SIGPENDING;
+       andi    r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
        beqi    r11, 1f;                /* Signals to handle, handle them */
 
        addik   r5, r1, 0;              /* Arg 1: struct pt_regs *regs */
        addi    r7, r0, 1;              /* Arg 3: int in_syscall */
-       bralid  r15, do_signal; /* Handle any signals */
+       bralid  r15, do_notify_resume;  /* Handle any signals */
        add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
 
 /* Finally, return to user state.  */
@@ -622,7 +622,7 @@ C_ENTRY(ret_from_exc):
        /* Maybe handle a signal */
 5:     lwi     r11, CURRENT_TASK, TS_THREAD_INFO;      /* get thread info */
        lwi     r11, r11, TI_FLAGS;     /* get flags in thread info */
-       andi    r11, r11, _TIF_SIGPENDING;
+       andi    r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
        beqi    r11, 1f;                /* Signals to handle, handle them */
 
        /*
@@ -635,10 +635,10 @@ C_ENTRY(ret_from_exc):
         * traps), but signal handlers may want to examine or change the
         * complete register state.  Here we save anything not saved by
         * the normal entry sequence, so that it may be safely restored
-        * (in a possibly modified form) after do_signal returns. */
+        * (in a possibly modified form) after do_notify_resume returns. */
        addik   r5, r1, 0;              /* Arg 1: struct pt_regs *regs */
        addi    r7, r0, 0;              /* Arg 3: int in_syscall */
-       bralid  r15, do_signal; /* Handle any signals */
+       bralid  r15, do_notify_resume;  /* Handle any signals */
        add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
 
 /* Finally, return to user state.  */
@@ -732,12 +732,12 @@ ret_from_irq:
     /* Maybe handle a signal */
 5:     lwi     r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */
        lwi     r11, r11, TI_FLAGS; /* get flags in thread info */
-       andi    r11, r11, _TIF_SIGPENDING;
+       andi    r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
        beqid   r11, no_intr_resched
 /* Handle a signal return; Pending signals should be in r18. */
        addi    r7, r0, 0; /* Arg 3: int in_syscall */
        addik   r5, r1, 0; /* Arg 1: struct pt_regs *regs */
-       bralid  r15, do_signal; /* Handle any signals */
+       bralid  r15, do_notify_resume;  /* Handle any signals */
        add     r6, r0, r0; /* Arg 2: sigset_t *oldset */
 
 /* Finally, return to user state. */
@@ -869,12 +869,12 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
        /* Maybe handle a signal */
 5:     lwi     r11, CURRENT_TASK, TS_THREAD_INFO;      /* get thread info */
        lwi     r11, r11, TI_FLAGS;     /* get flags in thread info */
-       andi    r11, r11, _TIF_SIGPENDING;
+       andi    r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
        beqi    r11, 1f;                /* Signals to handle, handle them */
 
        addik   r5, r1, 0;              /* Arg 1: struct pt_regs *regs */
        addi  r7, r0, 0;        /* Arg 3: int in_syscall */
-       bralid  r15, do_signal; /* Handle any signals */
+       bralid  r15, do_notify_resume;  /* Handle any signals */
        add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
 
 /* Finally, return to user state.  */
index fbdb026..449886d 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/personality.h>
 #include <linux/percpu.h>
 #include <linux/linkage.h>
+#include <linux/tracehook.h>
 #include <asm/entry.h>
 #include <asm/ucontext.h>
 #include <linux/uaccess.h>
@@ -42,8 +43,6 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
-
 asmlinkage long
 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
                struct pt_regs *regs)
@@ -340,7 +339,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
  * the kernel can handle, and then we build all the user-level signal handling
  * stack-frames in one go after that.
  */
-int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
+static int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
 {
        siginfo_t info;
        int signr;
@@ -350,14 +349,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
        printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
                        regs->r12, current_thread_info()->flags);
 #endif
-       /*
-        * We want the common case to go fast, which
-        * is why we may in certain cases get here from
-        * kernel mode. Just return without doing anything
-        * if so.
-        */
-       if (kernel_mode(regs))
-               return 1;
 
        if (current_thread_info()->status & TS_RESTORE_SIGMASK)
                oldset = &current->saved_sigmask;
@@ -397,3 +388,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
        /* Did we come from a system call? */
        return 0;
 }
+
+void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
+{
+       /*
+        * We want the common case to go fast, which
+        * is why we may in certain cases get here from
+        * kernel mode. Just return without doing anything
+        * if so.
+        */
+       if (kernel_mode(regs))
+               return;
+
+       if (test_thread_flag(TIF_SIGPENDING))
+               do_signal(regs, oldset, in_syscall);
+
+       if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
+               tracehook_notify_resume(regs);
+               if (current->replacement_session_keyring)
+                       key_replace_session_keyring();
+       }
+}