mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-07 14:24:18 +08:00
arm64: remove EL0 exception frame record
When entering an exception from EL0, the entry code creates a synthetic frame record with a NULL PC. This was used by the code introduced in commit:7326749801
("arm64: unwind: reference pt_regs via embedded stack frame") ... to discover exception entries on the stack and dump the associated pt_regs. Since the NULL PC was undesirable for the stacktrace, we added a special case to unwind_frame() to prevent the NULL PC from being logged. Since commit:a25ffd3a63
("arm64: traps: Don't print stack or raw PC/LR values in backtraces") ... we no longer try to dump the pt_regs as part of a stacktrace, and hence no longer need the synthetic exception record. This patch removes the synthetic exception record and the associated special case in unwind_frame(). Instead, EL0 exceptions set the FP to NULL, as is the case for other terminal records (e.g. when a kernel thread starts). The synthetic record for exceptions from EL1 is retrained as this has useful unwind information for the interrupted context. To make the terminal case a bit clearer, an explicit check is added to the start of unwind_frame(). This would otherwise be caught implicitly by the on_accessible_stack() checks. Reported-by: Mark Brown <broonie@kernel.org> Signed-off-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20210113173155.43063-1-broonie@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
19c329f680
commit
6106e1112c
@ -261,16 +261,16 @@ alternative_else_nop_endif
|
||||
stp lr, x21, [sp, #S_LR]
|
||||
|
||||
/*
|
||||
* In order to be able to dump the contents of struct pt_regs at the
|
||||
* time the exception was taken (in case we attempt to walk the call
|
||||
* stack later), chain it together with the stack frames.
|
||||
* For exceptions from EL0, terminate the callchain here.
|
||||
* For exceptions from EL1, create a synthetic frame record so the
|
||||
* interrupted code shows up in the backtrace.
|
||||
*/
|
||||
.if \el == 0
|
||||
stp xzr, xzr, [sp, #S_STACKFRAME]
|
||||
mov x29, xzr
|
||||
.else
|
||||
stp x29, x22, [sp, #S_STACKFRAME]
|
||||
.endif
|
||||
add x29, sp, #S_STACKFRAME
|
||||
.endif
|
||||
|
||||
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
|
||||
alternative_if_not ARM64_HAS_PAN
|
||||
|
@ -44,6 +44,10 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
|
||||
unsigned long fp = frame->fp;
|
||||
struct stack_info info;
|
||||
|
||||
/* Terminal record; nothing to unwind */
|
||||
if (!fp)
|
||||
return -EINVAL;
|
||||
|
||||
if (fp & 0xf)
|
||||
return -EINVAL;
|
||||
|
||||
@ -104,15 +108,6 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
|
||||
|
||||
frame->pc = ptrauth_strip_insn_pac(frame->pc);
|
||||
|
||||
/*
|
||||
* Frames created upon entry from EL0 have NULL FP and PC values, so
|
||||
* don't bother reporting these. Frames created by __noreturn functions
|
||||
* might have a valid FP even if PC is bogus, so only terminate where
|
||||
* both are NULL.
|
||||
*/
|
||||
if (!frame->fp && !frame->pc)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
NOKPROBE_SYMBOL(unwind_frame);
|
||||
|
Loading…
Reference in New Issue
Block a user