mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 05:04:02 +02:00
alpha: add ARCH_STACKWALK-based stacktrace support
Implement arch_stack_walk() for Alpha using a simple kernel stack scanning walker. Start from regs+1 for current tasks to skip pt_regs and use pcb.ksp for blocked tasks. Filter candidates with __kernel_text_address() and stop at stack bounds via kstack_end(). Enable CONFIG_STACKTRACE_SUPPORT and CONFIG_ARCH_STACKWALK so generic stacktrace users (dump_stack(), /proc/*/stack, SysRq backtraces, etc.) work on Alpha. This provides functional in-kernel stack traces without requiring frame pointer unwinding. Reviewed-by: Matt Turner <mattst88@gmail.com> Tested-by: Matt Turner <mattst88@gmail.com> Signed-off-by: Magnus Lindholm <linmag7@gmail.com> Link: https://lore.kernel.org/r/20260706170019.2941459-3-linmag7@gmail.com Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
This commit is contained in:
parent
8a2857bc2b
commit
46651c650f
|
|
@ -39,6 +39,7 @@ config ALPHA
|
|||
select MODULES_USE_ELF_RELA
|
||||
select ODD_RT_SIGACTION
|
||||
select OLD_SIGSUSPEND
|
||||
select ARCH_STACKWALK
|
||||
select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67
|
||||
select MMU_GATHER_NO_RANGE
|
||||
select MMU_GATHER_RCU_TABLE_FREE
|
||||
|
|
@ -80,6 +81,9 @@ config PGTABLE_LEVELS
|
|||
config AUDIT_ARCH
|
||||
bool
|
||||
|
||||
config STACKTRACE_SUPPORT
|
||||
def_bool y
|
||||
|
||||
menu "System setup"
|
||||
|
||||
choice
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ ccflags-y := -Wno-sign-compare
|
|||
|
||||
obj-y := head.o entry.o traps.o process.o osf_sys.o irq.o \
|
||||
irq_alpha.o signal.o setup.o ptrace.o time.o \
|
||||
systbls.o err_common.o io.o bugs.o termios.o
|
||||
systbls.o err_common.o io.o bugs.o termios.o \
|
||||
stacktrace.o
|
||||
|
||||
obj-$(CONFIG_VGA_HOSE) += console.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
|
|
|
|||
61
arch/alpha/kernel/stacktrace.c
Normal file
61
arch/alpha/kernel/stacktrace.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/kallsyms.h>
|
||||
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
static __always_inline unsigned long alpha_get_current_ksp(void)
|
||||
{
|
||||
unsigned long sp;
|
||||
|
||||
asm volatile("mov $30, %0" : "=r"(sp));
|
||||
return sp;
|
||||
}
|
||||
|
||||
static void alpha_scan_kernel_stack(unsigned long ksp,
|
||||
stack_trace_consume_fn consume_entry,
|
||||
void *cookie)
|
||||
{
|
||||
unsigned long *p = (unsigned long *)ksp;
|
||||
|
||||
if (unlikely(ksp & (sizeof(unsigned long) - 1)))
|
||||
return;
|
||||
|
||||
while (!kstack_end(p)) {
|
||||
unsigned long addr = READ_ONCE_NOCHECK(*p++);
|
||||
|
||||
if (!__kernel_text_address(addr))
|
||||
continue;
|
||||
|
||||
if (!consume_entry(cookie, addr))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
noinline void arch_stack_walk(stack_trace_consume_fn consume_entry,
|
||||
void *cookie,
|
||||
struct task_struct *task,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long ksp;
|
||||
|
||||
if (!task)
|
||||
task = current;
|
||||
|
||||
if (regs && task == current) {
|
||||
/*
|
||||
* pt_regs is stored on the kernel stack; regs+1 matches
|
||||
* what arch/alpha/kernel/traps.c uses as the trace start.
|
||||
*/
|
||||
ksp = (unsigned long)(regs + 1);
|
||||
} else if (task == current) {
|
||||
ksp = alpha_get_current_ksp();
|
||||
} else {
|
||||
ksp = task_thread_info(task)->pcb.ksp;
|
||||
}
|
||||
|
||||
alpha_scan_kernel_stack(ksp, consume_entry, cookie);
|
||||
}
|
||||
|
|
@ -28,6 +28,8 @@ SECTIONS
|
|||
TEXT_TEXT
|
||||
SCHED_TEXT
|
||||
LOCK_TEXT
|
||||
IRQENTRY_TEXT
|
||||
SOFTIRQENTRY_TEXT
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
} :text
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user