xtensa: add handling of TIF_NOTIFY_RESUME
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 24 Apr 2012 06:30:16 +0000 (02:30 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 22 May 2012 03:59:48 +0000 (23:59 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/xtensa/include/asm/thread_info.h
arch/xtensa/kernel/entry.S
arch/xtensa/kernel/signal.c

index 6abbedd..81abfd5 100644 (file)
@@ -131,6 +131,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_IRET               4       /* return with iret */
 #define TIF_MEMDIE             5       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    6       /* restore signal mask in do_signal() */
+#define TIF_NOTIFY_RESUME      7       /* callback before returning to user */
 #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
index b1bb6d7..7e62360 100644 (file)
@@ -409,14 +409,15 @@ common_exception_return:
        l32i    a4, a2, TI_FLAGS
 
        _bbsi.l a4, TIF_NEED_RESCHED, 3f
+       _bbsi.l a4, TIF_NOTIFY_RESUME, 2f
        _bbci.l a4, TIF_SIGPENDING, 4f
 
-       l32i    a4, a1, PT_DEPC
+2:     l32i    a4, a1, PT_DEPC
        bgeui   a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
 
        /* Call do_signal() */
 
-       movi    a4, do_signal   # int do_signal(struct pt_regs*, sigset_t*)
+       movi    a4, do_notify_resume    # int do_notify_resume(struct pt_regs*)
        mov     a6, a1
        callx4  a4
        j       1b
index bb00cc4..c5e4ec0 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ptrace.h>
 #include <linux/personality.h>
 #include <linux/freezer.h>
+#include <linux/tracehook.h>
 
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
@@ -446,16 +447,13 @@ asmlinkage long xtensa_sigaltstack(const stack_t __user *uss,
  * the kernel can handle, and then we build all the user-level signal handling
  * stack-frames in one go after that.
  */
-void do_signal(struct pt_regs *regs)
+static void do_signal(struct pt_regs *regs)
 {
        siginfo_t info;
        int signr;
        struct k_sigaction ka;
        sigset_t oldset;
 
-       if (!user_mode(regs))
-               return;
-
        if (try_to_freeze())
                goto no_signal;
 
@@ -542,3 +540,17 @@ no_signal:
        return;
 }
 
+void do_notify_resume(struct pt_regs *regs)
+{
+       if (!user_mode(regs))
+               return;
+
+       if (test_thread_flag(TIF_SIGPENDING))
+               do_signal(regs);
+
+       if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
+               tracehook_notify_resume(regs);
+               if (current->replacement_session_keyring)
+                       key_replace_session_keyring();
+       }
+}