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

Commit cfb0810e authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[PATCH] ARM: Don't try to send a signal to pid0



If we receive an unrecognised abort during boot, don't try to
send a signal to pid0, but instead report the current state.
This leads to less confusing debug reports.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 9b4311ee
Loading
Loading
Loading
Loading
+2 −10
Original line number Original line Diff line number Diff line
@@ -230,15 +230,7 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
	do_exit(SIGSEGV);
	do_exit(SIGSEGV);
}
}


void die_if_kernel(const char *str, struct pt_regs *regs, int err)
void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
{
	if (user_mode(regs))
    		return;

    	die(str, regs, err);
}

static void notify_die(const char *str, struct pt_regs *regs, siginfo_t *info,
		unsigned long err, unsigned long trap)
		unsigned long err, unsigned long trap)
{
{
	if (user_mode(regs)) {
	if (user_mode(regs)) {
+40 −35
Original line number Original line Diff line number Diff line
@@ -372,49 +372,50 @@ do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
static struct fsr_info {
static struct fsr_info {
	int	(*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
	int	(*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
	int	sig;
	int	sig;
	int	code;
	const char *name;
	const char *name;
} fsr_info[] = {
} fsr_info[] = {
	/*
	/*
	 * The following are the standard ARMv3 and ARMv4 aborts.  ARMv5
	 * The following are the standard ARMv3 and ARMv4 aborts.  ARMv5
	 * defines these to be "precise" aborts.
	 * defines these to be "precise" aborts.
	 */
	 */
	{ do_bad,		SIGSEGV, "vector exception"		   },
	{ do_bad,		SIGSEGV, 0,		"vector exception"		   },
	{ do_bad,		SIGILL,	 "alignment exception"		   },
	{ do_bad,		SIGILL,	 BUS_ADRALN,	"alignment exception"		   },
	{ do_bad,		SIGKILL, "terminal exception"		   },
	{ do_bad,		SIGKILL, 0,		"terminal exception"		   },
	{ do_bad,		SIGILL,	 "alignment exception"		   },
	{ do_bad,		SIGILL,	 BUS_ADRALN,	"alignment exception"		   },
	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
	{ do_bad,		SIGBUS,	 0,		"external abort on linefetch"	   },
	{ do_translation_fault,	SIGSEGV, "section translation fault"	   },
	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"section translation fault"	   },
	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
	{ do_bad,		SIGBUS,	 0,		"external abort on linefetch"	   },
	{ do_page_fault,	SIGSEGV, "page translation fault"	   },
	{ do_page_fault,	SIGSEGV, SEGV_MAPERR,	"page translation fault"	   },
	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
	{ do_bad,		SIGBUS,	 0,		"external abort on non-linefetch"  },
	{ do_bad,		SIGSEGV, "section domain fault"		   },
	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"section domain fault"		   },
	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
	{ do_bad,		SIGBUS,	 0,		"external abort on non-linefetch"  },
	{ do_bad,		SIGSEGV, "page domain fault"		   },
	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"page domain fault"		   },
	{ do_bad,		SIGBUS,	 "external abort on translation"   },
	{ do_bad,		SIGBUS,	 0,		"external abort on translation"	   },
	{ do_sect_fault,	SIGSEGV, "section permission fault"	   },
	{ do_sect_fault,	SIGSEGV, SEGV_ACCERR,	"section permission fault"	   },
	{ do_bad,		SIGBUS,	 "external abort on translation"   },
	{ do_bad,		SIGBUS,	 0,		"external abort on translation"	   },
	{ do_page_fault,	SIGSEGV, "page permission fault"	   },
	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"page permission fault"		   },
	/*
	/*
	 * The following are "imprecise" aborts, which are signalled by bit
	 * The following are "imprecise" aborts, which are signalled by bit
	 * 10 of the FSR, and may not be recoverable.  These are only
	 * 10 of the FSR, and may not be recoverable.  These are only
	 * supported if the CPU abort handler supports bit 10.
	 * supported if the CPU abort handler supports bit 10.
	 */
	 */
	{ do_bad,		SIGBUS,  "unknown 16"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 16"			   },
	{ do_bad,		SIGBUS,  "unknown 17"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 17"			   },
	{ do_bad,		SIGBUS,  "unknown 18"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 18"			   },
	{ do_bad,		SIGBUS,  "unknown 19"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 19"			   },
	{ do_bad,		SIGBUS,  "lock abort"			   }, /* xscale */
	{ do_bad,		SIGBUS,  0,		"lock abort"			   }, /* xscale */
	{ do_bad,		SIGBUS,  "unknown 21"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 21"			   },
	{ do_bad,		SIGBUS,  "imprecise external abort"	   }, /* xscale */
	{ do_bad,		SIGBUS,  BUS_OBJERR,	"imprecise external abort"	   }, /* xscale */
	{ do_bad,		SIGBUS,  "unknown 23"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 23"			   },
	{ do_bad,		SIGBUS,  "dcache parity error"		   }, /* xscale */
	{ do_bad,		SIGBUS,  0,		"dcache parity error"		   }, /* xscale */
	{ do_bad,		SIGBUS,  "unknown 25"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 25"			   },
	{ do_bad,		SIGBUS,  "unknown 26"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 26"			   },
	{ do_bad,		SIGBUS,  "unknown 27"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 27"			   },
	{ do_bad,		SIGBUS,  "unknown 28"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 28"			   },
	{ do_bad,		SIGBUS,  "unknown 29"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 29"			   },
	{ do_bad,		SIGBUS,  "unknown 30"			   },
	{ do_bad,		SIGBUS,  0,		"unknown 30"			   },
	{ do_bad,		SIGBUS,  "unknown 31"			   }
	{ do_bad,		SIGBUS,  0,		"unknown 31"			   }
};
};


void __init
void __init
@@ -435,15 +436,19 @@ asmlinkage void
do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
{
	const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);
	const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);
	struct siginfo info;


	if (!inf->fn(addr, fsr, regs))
	if (!inf->fn(addr, fsr, regs))
		return;
		return;


	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
		inf->name, fsr, addr);
		inf->name, fsr, addr);
	force_sig(inf->sig, current);

	show_pte(current->mm, addr);
	info.si_signo = inf->sig;
	die_if_kernel("Oops", regs, 0);
	info.si_errno = 0;
	info.si_code  = inf->code;
	info.si_addr  = (void __user *)addr;
	notify_die("", regs, &info, fsr, 0);
}
}


asmlinkage void
asmlinkage void
+3 −1
Original line number Original line Diff line number Diff line
@@ -85,7 +85,9 @@ struct pt_regs;
void die(const char *msg, struct pt_regs *regs, int err)
void die(const char *msg, struct pt_regs *regs, int err)
		__attribute__((noreturn));
		__attribute__((noreturn));


void die_if_kernel(const char *str, struct pt_regs *regs, int err);
struct siginfo;
void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
		unsigned long err, unsigned long trap);


void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
				       struct pt_regs *),
				       struct pt_regs *),