diff options
author | Will Deacon <will.deacon@arm.com> | 2018-02-20 14:46:05 +0100 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2018-03-06 19:52:23 +0100 |
commit | a1ece8216c41c9dbb4040f7b8b3fbcd17662c665 (patch) | |
tree | 9a29a92b0e56524f92328dc8cf9ca5fee688b049 /arch/arm64/kernel/traps.c | |
parent | arm64: signal: Force SIGKILL for unknown signals in force_signal_inject (diff) | |
download | linux-a1ece8216c41c9dbb4040f7b8b3fbcd17662c665.tar.xz 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.c | 28 |
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); } |