summaryrefslogtreecommitdiff
path: root/arch/xtensa
diff options
context:
space:
mode:
Diffstat (limited to 'arch/xtensa')
-rw-r--r--arch/xtensa/include/asm/thread_info.h1
-rw-r--r--arch/xtensa/kernel/entry.S5
-rw-r--r--arch/xtensa/kernel/signal.c20
3 files changed, 20 insertions, 6 deletions
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index 6abbedd..81abfd5 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/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)
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index b1bb6d7..7e62360 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/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
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index bb00cc4..c5e4ec0 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/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();
+ }
+}