From e76e69611e944ecc38aaf8fe3a7bebdc3c5daf84 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Fri, 22 Nov 2019 16:49:13 +0100 Subject: s390/unwind: stop gracefully at task pt_regs Consider reaching task pt_regs graceful unwinder termination. Task pt_regs itself never contains a valid state to which a task might return within the kernel context (user task pt_regs is a special case). Since we already avoid printing user task pt_regs and in most cases we don't even bother filling task pt_regs psw and r15 with something reasonable simply skip task pt_regs altogether. With this change unwind_error() now accurately represent whether unwinder reached task pt_regs successfully or failed along the way. Reviewed-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- arch/s390/kernel/unwind_bc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/unwind_bc.c b/arch/s390/kernel/unwind_bc.c index ac6cfab567d1..c5ebb8a4cdd6 100644 --- a/arch/s390/kernel/unwind_bc.c +++ b/arch/s390/kernel/unwind_bc.c @@ -36,6 +36,12 @@ static bool update_stack_info(struct unwind_state *state, unsigned long sp) return true; } +static inline bool is_task_pt_regs(struct unwind_state *state, + struct pt_regs *regs) +{ + return task_pt_regs(state->task) == regs; +} + bool unwind_next_frame(struct unwind_state *state) { struct stack_info *info = &state->stack_info; @@ -69,7 +75,7 @@ bool unwind_next_frame(struct unwind_state *state) if (!on_stack(info, sp, sizeof(struct pt_regs))) goto out_err; regs = (struct pt_regs *) sp; - if (READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE) + if (is_task_pt_regs(state, regs)) goto out_stop; ip = READ_ONCE_NOCHECK(regs->psw.addr); sp = READ_ONCE_NOCHECK(regs->gprs[15]); -- cgit v1.2.3