Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d79d853d authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle
Browse files

MIPS: mm: Add debug information for userland SIGSEGV signals.



Commit 41c594ab ("[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: default avatarMarkos 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent 9791554b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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"

+20 −9
Original line number Diff line number Diff line
@@ -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>
@@ -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
@@ -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,
@@ -201,15 +206,21 @@ bad_area_nosemaphore:
	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",
		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,
		       field, (unsigned long) regs->cp0_epc,
		       field, (unsigned long) regs->regs[31]);
#endif
				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 */