Skip to content

Commit

Permalink
MIPS: mm: Add debug information for userland SIGSEGV signals.
Browse files Browse the repository at this point in the history
Commit 41c594a ("[MIPS] MT: Improved multithreading support.")
removed useful debug information for userland segmentation faults.
This patch bring this back along with the ability to determine the
name of the object file where the EPC and RA registers point at.
Furthermore, we select the SYSCTL_EXCEPTION_TRACE symbol for MIPS
which is the de facto solution to turn userland exception logging
on and off via the /proc/sys/debug/exception-trace file.

Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9089/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Markos Chandras authored and Ralf Baechle committed Feb 16, 2015
1 parent 9791554 commit d79d853
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
1 change: 1 addition & 0 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ config MIPS
select CPU_PM if CPU_IDLE
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_BINFMT_ELF_STATE
select SYSCTL_EXCEPTION_TRACE

menu "Machine selection"

Expand Down
29 changes: 20 additions & 9 deletions arch/mips/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/ratelimit.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
Expand All @@ -28,6 +29,8 @@
#include <asm/highmem.h> /* For VMALLOC_END */
#include <linux/kdebug.h>

int show_unhandled_signals = 1;

/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
Expand All @@ -44,6 +47,8 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
int fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;

static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);

#if 0
printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
current->comm, current->pid, field, address, write,
Expand Down Expand Up @@ -201,15 +206,21 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
if (user_mode(regs)) {
tsk->thread.cp0_badvaddr = address;
tsk->thread.error_code = write;
#if 0
printk("do_page_fault() #2: sending SIGSEGV to %s for "
"invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n",
tsk->comm,
write ? "write access to" : "read access from",
field, address,
field, (unsigned long) regs->cp0_epc,
field, (unsigned long) regs->regs[31]);
#endif
if (show_unhandled_signals &&
unhandled_signal(tsk, SIGSEGV) &&
__ratelimit(&ratelimit_state)) {
pr_info("\ndo_page_fault(): sending SIGSEGV to %s for invalid %s %0*lx",
tsk->comm,
write ? "write access to" : "read access from",
field, address);
pr_info("epc = %0*lx in", field,
(unsigned long) regs->cp0_epc);
print_vma_addr(" ", regs->cp0_epc);
pr_info("ra = %0*lx in", field,
(unsigned long) regs->regs[31]);
print_vma_addr(" ", regs->regs[31]);
pr_info("\n");
}
info.si_signo = SIGSEGV;
info.si_errno = 0;
/* info.si_code has been set above */
Expand Down

0 comments on commit d79d853

Please sign in to comment.