mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 08:26:59 +00:00
s390/unwind: stop gracefully at user mode pt_regs in irq stack
Consider reaching user mode pt_regs at the bottom of irq stack graceful unwinder termination. This is the case when irq/mcck/ext interrupt arrives while in user mode. Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
c23587c92f
commit
eef06cbf67
1 changed files with 11 additions and 4 deletions
|
@ -36,10 +36,17 @@ static bool update_stack_info(struct unwind_state *state, unsigned long sp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_task_pt_regs(struct unwind_state *state,
|
static inline bool is_final_pt_regs(struct unwind_state *state,
|
||||||
struct pt_regs *regs)
|
struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
return task_pt_regs(state->task) == regs;
|
/* user mode or kernel thread pt_regs at the bottom of task stack */
|
||||||
|
if (task_pt_regs(state->task) == regs)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* user mode pt_regs at the bottom of irq stack */
|
||||||
|
return state->stack_info.type == STACK_TYPE_IRQ &&
|
||||||
|
state->stack_info.end - sizeof(struct pt_regs) == (unsigned long)regs &&
|
||||||
|
READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unwind_next_frame(struct unwind_state *state)
|
bool unwind_next_frame(struct unwind_state *state)
|
||||||
|
@ -80,7 +87,7 @@ bool unwind_next_frame(struct unwind_state *state)
|
||||||
if (!on_stack(info, sp, sizeof(struct pt_regs)))
|
if (!on_stack(info, sp, sizeof(struct pt_regs)))
|
||||||
goto out_err;
|
goto out_err;
|
||||||
regs = (struct pt_regs *) sp;
|
regs = (struct pt_regs *) sp;
|
||||||
if (is_task_pt_regs(state, regs))
|
if (is_final_pt_regs(state, regs))
|
||||||
goto out_stop;
|
goto out_stop;
|
||||||
ip = READ_ONCE_NOCHECK(regs->psw.addr);
|
ip = READ_ONCE_NOCHECK(regs->psw.addr);
|
||||||
sp = READ_ONCE_NOCHECK(regs->gprs[15]);
|
sp = READ_ONCE_NOCHECK(regs->gprs[15]);
|
||||||
|
|
Loading…
Reference in a new issue