Browse Source

xtensa: add handling of TIF_NOTIFY_RESUME

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Al Viro 13 years ago
parent
commit
a53bb24e76
3 changed files with 20 additions and 6 deletions
  1. 1 0
      arch/xtensa/include/asm/thread_info.h
  2. 3 2
      arch/xtensa/kernel/entry.S
  3. 16 4
      arch/xtensa/kernel/signal.c

+ 1 - 0
arch/xtensa/include/asm/thread_info.h

@@ -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)

+ 3 - 2
arch/xtensa/kernel/entry.S

@@ -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

+ 16 - 4
arch/xtensa/kernel/signal.c

@@ -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();
+	}
+}