alpha: select SYSCTL_EXCEPTION_TRACE

Report unhandled user faults the way other architectures do, and hook up
the debug.exception-trace sysctl that controls the reporting.

The message gives the faulting address, the PC and the user stack
pointer, and is rate limited.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Matt Turner <mattst88@gmail.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://lore.kernel.org/r/20260905-arch-kconfig-options-v2-v2-17-83e8245761a2@gmail.com
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
This commit is contained in:
Matt Turner 2026-09-05 15:29:38 -04:00 committed by Magnus Lindholm
parent 4630bd7885
commit e517a172b7
2 changed files with 30 additions and 0 deletions

View File

@ -61,6 +61,7 @@ config ALPHA
select MMU_GATHER_NO_RANGE
select MMU_GATHER_RCU_TABLE_FREE
select SPARSEMEM_EXTREME if SPARSEMEM
select SYSCTL_EXCEPTION_TRACE
select ZONE_DMA
select TRACE_IRQFLAGS_SUPPORT
select ARCH_WANT_FRAME_POINTERS

View File

@ -27,8 +27,32 @@
#include <linux/uaccess.h>
#include <linux/perf_event.h>
#include <asm/pal.h>
extern void die_if_kernel(char *,struct pt_regs *,long, unsigned long *);
int show_unhandled_signals = 1;
static void
show_signal_msg(struct pt_regs *regs, unsigned long address, int signo,
const char *desc)
{
const char *level;
if (!show_unhandled_signals || !unhandled_signal(current, signo))
return;
if (!printk_ratelimit())
return;
/* Losing init is fatal, so shout about it. */
level = task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG;
printk("%s%s[%d]: %s at %016lx pc %016lx sp %016lx\n",
level, current->comm, task_pid_nr(current), desc,
address, regs->pc, rdusp());
print_vma_addr(KERN_CONT " in ", regs->pc);
printk(KERN_CONT "\n");
}
/*
* Force a new ASN for a task.
@ -217,12 +241,17 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
mmap_read_unlock(mm);
/* Send a sigbus, regardless of whether we were in kernel
or user mode. */
if (user_mode(regs))
show_signal_msg(regs, address, SIGBUS, "bus error");
force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *) address);
if (!user_mode(regs))
goto no_context;
return;
do_sigsegv:
show_signal_msg(regs, address, SIGSEGV,
si_code == SEGV_MAPERR ? "unmapped access"
: "access violation");
force_sig_fault(SIGSEGV, si_code, (void __user *) address);
return;