summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/traps.c
diff options
context:
space:
mode:
authorWill Deacon2018-02-20 14:46:05 +0100
committerWill Deacon2018-03-06 19:52:23 +0100
commita1ece8216c41c9dbb4040f7b8b3fbcd17662c665 (patch)
tree9a29a92b0e56524f92328dc8cf9ca5fee688b049 /arch/arm64/kernel/traps.c
parentarm64: signal: Force SIGKILL for unknown signals in force_signal_inject (diff)
downloadkernel-qcow2-linux-a1ece8216c41c9dbb4040f7b8b3fbcd17662c665.tar.gz
kernel-qcow2-linux-a1ece8216c41c9dbb4040f7b8b3fbcd17662c665.tar.xz
kernel-qcow2-linux-a1ece8216c41c9dbb4040f7b8b3fbcd17662c665.zip
arm64: Introduce arm64_force_sig_info and hook up in arm64_notify_die
In preparation for consolidating our handling of printing unhandled signals, introduce a wrapper around force_sig_info which can act as the canonical place for dealing with show_unhandled_signals. Initially, we just hook this up to arm64_notify_die. Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/traps.c')
-rw-r--r--arch/arm64/kernel/traps.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 3f52c07b4bf4..00516f3956e4 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -223,13 +223,39 @@ void die(const char *str, struct pt_regs *regs, int err)
do_exit(SIGSEGV);
}
+void arm64_force_sig_info(struct siginfo *info, const char *str,
+ struct task_struct *tsk)
+{
+ unsigned int esr = tsk->thread.fault_code;
+ struct pt_regs *regs = task_pt_regs(tsk);
+
+ if (!unhandled_signal(tsk, info->si_signo))
+ goto send_sig;
+
+ if (!show_unhandled_signals_ratelimited())
+ goto send_sig;
+
+ pr_info("%s[%d]: unhandled exception: ", tsk->comm, task_pid_nr(tsk));
+ if (esr)
+ pr_cont("%s, ESR 0x%08x, ", esr_get_class_string(esr), esr);
+
+ pr_cont("%s", str);
+ print_vma_addr(KERN_CONT " in ", regs->pc);
+ pr_cont("\n");
+ __show_regs(regs);
+
+send_sig:
+ force_sig_info(info->si_signo, info, tsk);
+}
+
void arm64_notify_die(const char *str, struct pt_regs *regs,
struct siginfo *info, int err)
{
if (user_mode(regs)) {
+ WARN_ON(regs != current_pt_regs());
current->thread.fault_address = 0;
current->thread.fault_code = err;
- force_sig_info(info->si_signo, info, current);
+ arm64_force_sig_info(info, str, current);
} else {
die(str, regs, err);
}