arm64: stacktrace: restore terminal records
We removed the terminal frame records in commit:6106e1112c
("arm64: remove EL0 exception frame record") ... on the assumption that as we no longer used them to find the pt_regs at exception boundaries, they were no longer necessary. However, Leo reports that as an unintended side-effect, this causes traces which cross secondary_start_kernel to terminate one entry too late, with a spurious "0" entry. There are a few ways we could sovle this, but as we're planning to use terminal records for RELIABLE_STACKTRACE, let's revert the logic change for now, keeping the update comments and accounting for the changes in commit:3c02600144
("arm64: stacktrace: Report when we reach the end of the stack") This is effectively a partial revert of commit:6106e1112c
("arm64: remove EL0 exception frame record") Signed-off-by: Mark Rutland <mark.rutland@arm.com> Fixes:6106e1112c
("arm64: remove EL0 exception frame record") Reported-by: Leo Yan <leo.yan@linaro.org> Tested-by: Leo Yan <leo.yan@linaro.org> Cc: Will Deacon <will@kernel.org> Cc: Mark Brown <broonie@kernel.org> Cc: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com> Link: https://lore.kernel.org/r/20210429104813.GA33550@C02TD0UTHF1T.local Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
388708028e
commit
8533d5bfad
|
@ -283,16 +283,16 @@ alternative_else_nop_endif
|
|||
stp lr, x21, [sp, #S_LR]
|
||||
|
||||
/*
|
||||
* For exceptions from EL0, terminate the callchain here.
|
||||
* For exceptions from EL0, create a terminal frame record.
|
||||
* For exceptions from EL1, create a synthetic frame record so the
|
||||
* interrupted code shows up in the backtrace.
|
||||
*/
|
||||
.if \el == 0
|
||||
mov x29, xzr
|
||||
stp xzr, xzr, [sp, #S_STACKFRAME]
|
||||
.else
|
||||
stp x29, x22, [sp, #S_STACKFRAME]
|
||||
add x29, sp, #S_STACKFRAME
|
||||
.endif
|
||||
add x29, sp, #S_STACKFRAME
|
||||
|
||||
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
|
||||
alternative_if_not ARM64_HAS_PAN
|
||||
|
|
|
@ -68,10 +68,6 @@ 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 -ENOENT;
|
||||
|
||||
if (fp & 0xf)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -132,6 +128,12 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
|
|||
|
||||
frame->pc = ptrauth_strip_insn_pac(frame->pc);
|
||||
|
||||
/*
|
||||
* This is a terminal record, so we have finished unwinding.
|
||||
*/
|
||||
if (!frame->fp && !frame->pc)
|
||||
return -ENOENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
NOKPROBE_SYMBOL(unwind_frame);
|
||||
|
|
Loading…
Reference in New Issue