linux/arch/arm64/kernel
Mark Rutland 1ced45535d arm64: stacktrace: don't trace arch_stack_walk()
commit c607ab4f91 upstream.

We recently converted arm64 to use arch_stack_walk() in commit:

  5fc57df2f6 ("arm64: stacktrace: Convert to ARCH_STACKWALK")

The core stacktrace code expects that (when tracing the current task)
arch_stack_walk() starts a trace at its caller, and does not include
itself in the trace. However, arm64's arch_stack_walk() includes itself,
and so traces include one more entry than callers expect. The core
stacktrace code which calls arch_stack_walk() tries to skip a number of
entries to prevent itself appearing in a trace, and the additional entry
prevents skipping one of the core stacktrace functions, leaving this in
the trace unexpectedly.

We can fix this by having arm64's arch_stack_walk() begin the trace with
its caller. The first value returned by the trace will be
__builtin_return_address(0), i.e. the caller of arch_stack_walk(). The
first frame record to be unwound will be __builtin_frame_address(1),
i.e. the caller's frame record. To prevent surprises, arch_stack_walk()
is also marked noinline.

While __builtin_frame_address(1) is not safe in portable code, local GCC
developers have confirmed that it is safe on arm64. To find the caller's
frame record, the builtin can safely dereference the current function's
frame record or (in theory) could stash the original FP into another GPR
at function entry time, neither of which are problematic.

Prior to this patch, the tracing code would unexpectedly show up in
traces of the current task, e.g.

| # cat /proc/self/stack
| [<0>] stack_trace_save_tsk+0x98/0x100
| [<0>] proc_pid_stack+0xb4/0x130
| [<0>] proc_single_show+0x60/0x110
| [<0>] seq_read_iter+0x230/0x4d0
| [<0>] seq_read+0xdc/0x130
| [<0>] vfs_read+0xac/0x1e0
| [<0>] ksys_read+0x6c/0xfc
| [<0>] __arm64_sys_read+0x20/0x30
| [<0>] el0_svc_common.constprop.0+0x60/0x120
| [<0>] do_el0_svc+0x24/0x90
| [<0>] el0_svc+0x2c/0x54
| [<0>] el0_sync_handler+0x1a4/0x1b0
| [<0>] el0_sync+0x170/0x180

After this patch, the tracing code will not show up in such traces:

| # cat /proc/self/stack
| [<0>] proc_pid_stack+0xb4/0x130
| [<0>] proc_single_show+0x60/0x110
| [<0>] seq_read_iter+0x230/0x4d0
| [<0>] seq_read+0xdc/0x130
| [<0>] vfs_read+0xac/0x1e0
| [<0>] ksys_read+0x6c/0xfc
| [<0>] __arm64_sys_read+0x20/0x30
| [<0>] el0_svc_common.constprop.0+0x60/0x120
| [<0>] do_el0_svc+0x24/0x90
| [<0>] el0_svc+0x2c/0x54
| [<0>] el0_sync_handler+0x1a4/0x1b0
| [<0>] el0_sync+0x170/0x180

Erring on the side of caution, I've given this a spin with a bunch of
toolchains, verifying the output of /proc/self/stack and checking that
the assembly looked sound. For GCC (where we require version 5.1.0 or
later) I tested with the kernel.org crosstool binares for versions
5.5.0, 6.4.0, 6.5.0, 7.3.0, 7.5.0, 8.1.0, 8.3.0, 8.4.0, 9.2.0, and
10.1.0. For clang (where we require version 10.0.1 or later) I tested
with the llvm.org binary releases of 11.0.0, and 11.0.1.

Fixes: 5fc57df2f6 ("arm64: stacktrace: Convert to ARCH_STACKWALK")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Chen Jun <chenjun102@huawei.com>
Cc: Marco Elver <elver@google.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: <stable@vger.kernel.org> # 5.10.x
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210319184106.5688-1-mark.rutland@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-03-30 14:31:54 +02:00
..
probes arm64: uprobe: Return EOPNOTSUPP for AARCH32 instruction probing 2021-03-04 11:38:36 +01:00
vdso More arm64 updates for 5.10 2020-10-23 09:46:16 -07:00
vdso32 arm64: vdso32: Allow ld.lld to properly link the VDSO 2020-10-26 13:17:41 +00:00
.gitignore
acpi_numa.c
acpi_parking_protocol.c
acpi.c arm64: permit ACPI core to map kernel memory used for table overrides 2020-09-30 22:27:51 +01:00
alternative.c arm64/alternatives: don't patch up internal branches 2020-07-09 14:57:59 +01:00
armv8_deprecated.c
asm-offsets.c KVM: arm64: Make struct kvm_regs userspace-only 2020-07-07 09:28:38 +01:00
cacheinfo.c
cpu_errata.c arm64: cpu_errata: Apply Erratum 845719 to KRYO2XX Silver 2020-11-13 09:47:08 +00:00
cpu_ops.c
cpu-reset.h
cpu-reset.S arm64/relocate_kernel: remove redundant code 2020-09-11 19:06:25 +01:00
cpufeature.c arm64: Extend workaround for erratum 1024718 to all versions of Cortex-A55 2021-03-04 11:38:35 +01:00
cpuidle.c
cpuinfo.c arm64: avoid -Woverride-init warning 2020-10-28 13:38:36 +00:00
crash_core.c arm64/crash_core: Export TCR_EL1.T1SZ in vmcoreinfo 2020-07-02 17:56:49 +01:00
crash_dump.c
debug-monitors.c arm64: Improve diagnostics when trapping BRK with FAULT_BRK_IMM 2020-09-18 16:35:54 +01:00
efi-entry.S arm64 updates for 5.8 2020-06-01 15:18:27 -07:00
efi-header.S arm64: efi: increase EFI PE/COFF header padding to 64 KB 2020-10-28 14:02:03 +00:00
efi-rt-wrapper.S Merge branch 'for-next/scs' into for-next/core 2020-05-28 18:03:40 +01:00
efi.c treewide: Convert macro and uses of __section(foo) to __section("foo") 2020-10-25 14:51:49 -07:00
entry-common.c arm64: entry: fix EL1 debug transitions 2020-11-30 12:11:38 +00:00
entry-fpsimd.S arm64/sve: Implement a helper to load SVE registers from FPSIMD state 2020-09-21 18:06:33 +01:00
entry-ftrace.S arm64: entry-ftrace.S: Update comment to indicate that x18 is live 2020-05-18 17:47:50 +01:00
entry.S arm64: entry: fix non-NMI user<->kernel transitions 2020-11-30 12:11:38 +00:00
fpsimd.c arm64: reject prctl(PR_PAC_RESET_KEYS) on compat tasks 2020-10-15 10:50:09 +01:00
ftrace.c arm64: ftrace: Change CONFIG_FTRACE_WITH_REGS to CONFIG_DYNAMIC_FTRACE_WITH_REGS 2020-06-08 15:44:59 +01:00
head.S arm64: mm: use a 48-bit ID map when possible on 52-bit VA builds 2021-03-17 17:06:34 +01:00
hibernate-asm.S arm64: kernel: Convert to modern annotations for assembly functions 2020-05-04 12:46:03 +01:00
hibernate.c Merge branch 'for-next/mte' into for-next/core 2020-10-02 12:16:11 +01:00
hw_breakpoint.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
hyp-stub.S arm64: kernel: Convert to modern annotations for assembly functions 2020-05-04 12:46:03 +01:00
image-vars.h KVM/arm64 fixes for 5.10, take #1 2020-10-30 13:25:09 -04:00
image.h arm64: get rid of TEXT_OFFSET 2020-09-07 15:00:52 +01:00
insn.c arm64: kprobe: disable probe of fault prone ptrauth instruction 2020-09-14 12:07:02 +01:00
io.c
irq.c arm64: entry: move el1 irq/nmi logic to C 2020-11-30 12:11:38 +00:00
jump_label.c
kaslr.c arm64: kaslr: Use standard early random function 2020-08-07 09:10:11 -07:00
kexec_image.c arm64: kexec_file: Fix sparse warning 2020-11-10 13:11:44 +00:00
kgdb.c arm64: kgdb: Fix single-step exception handling oops 2020-07-08 22:18:54 +01:00
kuser32.S
machine_kexec_file.c arm64: kexec_file: fix memory leakage in create_dtb() when fdt_open_into() fails 2021-03-04 11:38:36 +01:00
machine_kexec.c arm64: fix the flush_icache_range arguments in machine_kexec 2020-05-11 12:02:14 +01:00
Makefile Merge branch 'for-next/mte' into for-next/core 2020-10-02 12:16:11 +01:00
module-plts.c arm64/module: set trampoline section flags regardless of CONFIG_DYNAMIC_FTRACE 2020-09-02 08:35:33 +01:00
module.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
mte.c arm64: mte: Allow PTRACE_PEEKMTETAGS access to the zero page 2021-02-17 11:02:28 +01:00
paravirt.c arm64: paravirt: Initialize steal time when cpu is online 2020-09-17 18:12:18 +01:00
pci.c
perf_callchain.c arm64: stacktrace: Make stack walk callback consistent with generic code 2020-09-18 14:24:16 +01:00
perf_event.c arm64: perf: Fix 64-bit event counter read truncation 2021-03-17 17:06:28 +01:00
perf_regs.c perf/arch: Remove perf_sample_data::regs_user_copy 2020-11-09 18:12:34 +01:00
pointer_auth.c arm64: reject prctl(PR_PAC_RESET_KEYS) on compat tasks 2020-10-15 10:50:09 +01:00
process.c arm64 fixes for -rc7 2020-12-02 12:27:37 -08:00
proton-pack.c arm64: proton-pack: Add KRYO2XX silver CPUs to spectre-v2 safe-list 2020-11-13 09:47:08 +00:00
psci.c arm64: psci: Avoid printing in cpu_psci_cpu_die() 2020-11-10 13:11:44 +00:00
ptrace.c arm64: ptrace: Fix seccomp of traced syscall -1 (NO_SYSCALL) 2021-03-04 11:38:32 +01:00
reloc_test_core.c
reloc_test_syms.S arm64: kernel: Convert to modern annotations for assembly functions 2020-05-04 12:46:03 +01:00
relocate_kernel.S arm64/relocate_kernel: remove redundant code 2020-09-11 19:06:25 +01:00
return_address.c arm64: stacktrace: Make stack walk callback consistent with generic code 2020-09-18 14:24:16 +01:00
scs.c scs: Move DEFINE_SCS macro into core code 2020-05-18 17:47:48 +01:00
sdei.c arm64: entry: fix NMI {user, kernel}->kernel transitions 2020-11-30 12:11:38 +00:00
setup.c memblock: use separate iterators for memory and reserved regions 2020-10-13 18:38:35 -07:00
signal.c arm64: entry: remove redundant IRQ flag tracing 2021-01-27 11:55:07 +01:00
signal32.c arm64: compat: Always use sigpage for sigreturn trampoline 2020-06-23 14:56:24 +01:00
sigreturn32.S
sleep.S Merge branch 'for-next/bti' into for-next/core 2020-05-28 18:00:51 +01:00
smccc-call.S arm64/kernel: Remove needless Call Frame Information annotations 2020-09-01 09:50:36 +02:00
smp_spin_table.c treewide: Convert macro and uses of __section(foo) to __section("foo") 2020-10-25 14:51:49 -07:00
smp.c arm64: smp: Tell RCU about CPUs that fail to come online 2020-11-10 13:11:44 +00:00
stacktrace.c arm64: stacktrace: don't trace arch_stack_walk() 2021-03-30 14:31:54 +02:00
suspend.c arm64: spectre: Prevent lockdep splat on v4 mitigation enable path 2021-03-04 11:38:36 +01:00
sys_compat.c
sys.c
sys32.c
syscall.c arm64: entry: remove redundant IRQ flag tracing 2021-01-27 11:55:07 +01:00
time.c
topology.c Power management updates for 5.10-rc1 2020-10-14 10:45:41 -07:00
trace-events-emulation.h
traps.c arm64: entry: fix NMI {user, kernel}->kernel transitions 2020-11-30 12:11:38 +00:00
vdso.c arm64: vdso: Fix unusual formatting in *setup_additional_pages() 2020-09-01 13:37:57 +01:00
vmlinux.lds.S arm64: vmlinux.lds: account for spurious empty .igot.plt sections 2020-10-28 13:44:24 +00:00