mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
alpha: fix stale user_stack_pointer()
PALcode keeps the user stack pointer in the PCB, not the trap frame, so
pt_regs->usp is only valid where entry code stores it: entSys,
do_entArith() and do_entIF(). Interrupts, page faults and unaligned
traps leave it stale, and ptrace and /proc/<pid>/syscall read it
through user_stack_pointer().
A user-mode pt_regs is at the top of its task's stack, so find the
thread_info from it and use rdusp() for current or pcb.usp otherwise,
as KSTK_ESP() and the regset code already do.
Fixes: 8a2857bc2b ("alpha: enable regset-based ptrace and core dumps")
Assisted-by: Claude:claude-opus-5-5
Reviewed-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Acked-by: Ian Rogers <irogers@google.com>
Signed-off-by: Matt Turner <mattst88@gmail.com>
Link: https://lore.kernel.org/r/20261018-alpha-perf-regs-v3-v3-1-52be85332c57@gmail.com
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
This commit is contained in:
parent
b9fad53a62
commit
bceba446fa
|
|
@ -26,12 +26,7 @@ static inline unsigned long regs_return_value(struct pt_regs *regs)
|
|||
return regs->r0;
|
||||
}
|
||||
|
||||
/* Helpers for working with the user stack pointer */
|
||||
static inline unsigned long user_stack_pointer(struct pt_regs *regs)
|
||||
{
|
||||
/* Valid for user-mode regs */
|
||||
return regs->usp;
|
||||
}
|
||||
unsigned long user_stack_pointer(struct pt_regs *regs);
|
||||
|
||||
static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -440,6 +440,18 @@ ptrace_cancel_bpt(struct task_struct * child)
|
|||
return (nsaved != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* PALcode keeps the user stack pointer in the PCB, not the trap frame.
|
||||
* A user-mode pt_regs sits at the top of its task's stack, so the
|
||||
* thread_info is at the base.
|
||||
*/
|
||||
unsigned long user_stack_pointer(struct pt_regs *regs)
|
||||
{
|
||||
struct thread_info *ti = (void *)((unsigned long)regs & -THREAD_SIZE);
|
||||
|
||||
return ti == current_thread_info() ? rdusp() : ti->pcb.usp;
|
||||
}
|
||||
|
||||
void user_enable_single_step(struct task_struct *child)
|
||||
{
|
||||
/* Mark single stepping. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user