linux/arch/riscv/kernel
Matthew Bystrin a2a4d4a6a0
riscv: stacktrace: fixed walk_stackframe()
If the load access fault occures in a leaf function (with
CONFIG_FRAME_POINTER=y), when wrong stack trace will be displayed:

[<ffffffff804853c2>] regmap_mmio_read32le+0xe/0x1c
---[ end trace 0000000000000000 ]---

Registers dump:
    ra     0xffffffff80485758 <regmap_mmio_read+36>
    sp     0xffffffc80200b9a0
    fp     0xffffffc80200b9b0
    pc     0xffffffff804853ba <regmap_mmio_read32le+6>

Stack dump:
    0xffffffc80200b9a0:  0xffffffc80200b9e0  0xffffffc80200b9e0
    0xffffffc80200b9b0:  0xffffffff8116d7e8  0x0000000000000100
    0xffffffc80200b9c0:  0xffffffd8055b9400  0xffffffd8055b9400
    0xffffffc80200b9d0:  0xffffffc80200b9f0  0xffffffff8047c526
    0xffffffc80200b9e0:  0xffffffc80200ba30  0xffffffff8047fe9a

The assembler dump of the function preambula:
    add     sp,sp,-16
    sd      s0,8(sp)
    add     s0,sp,16

In the fist stack frame, where ra is not stored on the stack we can
observe:

        0(sp)                  8(sp)
        .---------------------------------------------.
    sp->|       frame->fp      | frame->ra (saved fp) |
        |---------------------------------------------|
    fp->|         ....         |         ....         |
        |---------------------------------------------|
        |                      |                      |

and in the code check is performed:
	if (regs && (regs->epc == pc) && (frame->fp & 0x7))

I see no reason to check frame->fp value at all, because it is can be
uninitialized value on the stack. A better way is to check frame->ra to
be an address on the stack. After the stacktrace shows as expect:

[<ffffffff804853c2>] regmap_mmio_read32le+0xe/0x1c
[<ffffffff80485758>] regmap_mmio_read+0x24/0x52
[<ffffffff8047c526>] _regmap_bus_reg_read+0x1a/0x22
[<ffffffff8047fe9a>] _regmap_read+0x5c/0xea
[<ffffffff80480376>] _regmap_update_bits+0x76/0xc0
...
---[ end trace 0000000000000000 ]---
As pointed by Samuel Holland it is incorrect to remove check of the stackframe
entirely.

Changes since v2 [2]:
 - Add accidentally forgotten curly brace

Changes since v1 [1]:
 - Instead of just dropping frame->fp check, replace it with validation of
   frame->ra, which should be a stack address.
 - Move frame pointer validation into the separate function.

[1] https://lore.kernel.org/linux-riscv/20240426072701.6463-1-dev.mbstr@gmail.com/
[2] https://lore.kernel.org/linux-riscv/20240521131314.48895-1-dev.mbstr@gmail.com/

Fixes: f766f77a74 ("riscv/stacktrace: Fix stack output without ra on the stack top")
Signed-off-by: Matthew Bystrin <dev.mbstr@gmail.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://lore.kernel.org/r/20240521191727.62012-1-dev.mbstr@gmail.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2024-05-22 16:12:49 -07:00
..
compat_vdso Makefile: remove redundant tool coverage variables 2024-05-14 23:35:48 +09:00
pi Makefile: remove redundant tool coverage variables 2024-05-14 23:35:48 +09:00
probes The usual shower of singleton fixes and minor series all over MM, 2024-05-19 09:21:03 -07:00
tests treewide: replace or remove redundant def_bool in Kconfig files 2024-02-20 20:47:45 +09:00
vdso Makefile: remove redundant tool coverage variables 2024-05-14 23:35:48 +09:00
.gitignore
acpi.c
alternative.c riscv: errata: Rename defines for Andes 2024-03-12 07:13:12 -07:00
asm-offsets.c ftrace: riscv: move from REGS to ARGS 2024-05-22 16:12:48 -07:00
cacheinfo.c
cfi.c bpf, riscv64/cfi: Support kCFI + BPF on riscv64 2024-03-06 15:18:16 -08:00
compat_signal.c
compat_syscall_table.c
copy-unaligned.h
copy-unaligned.S riscv: Use SYM_*() assembly macros instead of deprecated ones 2023-11-06 09:42:47 -08:00
cpu-hotplug.c riscv: Use the same CPU operations for all CPUs 2024-01-04 15:03:07 -08:00
cpu.c Merge patch series "Linux RISC-V AIA Preparatory Series" 2023-11-08 18:57:17 -08:00
cpu_ops.c riscv: Use the same CPU operations for all CPUs 2024-01-04 15:03:07 -08:00
cpu_ops_sbi.c riscv: Remove unused members from struct cpu_operations 2024-01-04 15:03:06 -08:00
cpu_ops_spinwait.c riscv: Remove unused members from struct cpu_operations 2024-01-04 15:03:06 -08:00
cpufeature.c RISC-V Patches for the 6.9 Merge Window 2024-03-22 10:41:13 -07:00
crash_dump.c
crash_save_regs.S
efi-header.S
efi.c riscv: Use accessors to page table entries instead of direct dereference 2023-12-20 10:48:15 -08:00
elf_kexec.c fix missing vmalloc.h includes 2024-04-25 20:55:49 -07:00
entry.S riscv: blacklist assembly symbols for kprobe 2024-01-24 15:59:42 -08:00
fpu.S riscv: Use SYM_*() assembly macros instead of deprecated ones 2023-11-06 09:42:47 -08:00
ftrace.c ftrace: riscv: move from REGS to ARGS 2024-05-22 16:12:48 -07:00
head.h
head.S Merge patch series "Fix XIP boot and make XIP testable in QEMU" 2024-01-09 20:10:39 -08:00
hibernate-asm.S riscv: Use SYM_*() assembly macros instead of deprecated ones 2023-11-06 09:42:47 -08:00
hibernate.c
image-vars.h
irq.c Merge patch "drivers: perf: Do not broadcast to other cpus when starting a counter" 2023-11-09 06:44:13 -08:00
jump_label.c
kernel_mode_vector.c riscv: vector: allow kernel-mode Vector with preemption 2024-01-16 07:14:02 -08:00
kexec_relocate.S
kgdb.c
machine_kexec.c kexec_file, riscv: print out debugging message if required 2023-12-20 15:02:57 -08:00
machine_kexec_file.c
Makefile RISC-V Patches for the 6.9 Merge Window 2024-03-22 10:41:13 -07:00
mcount-dyn.S ftrace: riscv: move from REGS to ARGS 2024-05-22 16:12:48 -07:00
mcount.S riscv: remove MCOUNT_NAME workaround 2024-02-22 15:38:54 -08:00
module-sections.c
module.c arch: make execmem setup available regardless of CONFIG_MODULES 2024-05-14 00:31:44 -07:00
paravirt.c RISC-V: KVM: Rename the SBI_STA_SHMEM_DISABLE to a generic name 2024-04-22 11:13:52 +05:30
patch.c RISC-V Patches for the 6.10 Merge Window, Part 1 2024-05-22 09:56:00 -07:00
perf_callchain.c
perf_regs.c
process.c riscv: process: Fix kernel gp leakage 2024-04-04 12:35:05 -07:00
ptrace.c Merge patch series "riscv: Introduce compat-mode helpers & improve arch_get_mmap_end()" 2024-03-20 08:56:05 -07:00
reset.c
return_address.c riscv: add CALLER_ADDRx support 2024-02-22 12:17:47 -08:00
riscv_ksyms.c
sbi-ipi.c riscv: Use IPIs for remote cache/TLB flushes by default 2024-04-29 10:49:26 -07:00
sbi.c RISC-V: Add SBI debug console helper routines 2024-01-10 07:04:03 -08:00
setup.c Driver core changes for 6.8-rc1 2024-01-18 09:48:40 -08:00
signal.c riscv: Fix vector state restore in rt_sigreturn() 2024-04-03 16:10:25 -07:00
smp.c riscv: Use IPIs for remote cache/TLB flushes by default 2024-04-29 10:49:26 -07:00
smpboot.c riscv: Flush the instruction cache during SMP bringup 2024-04-29 10:49:24 -07:00
soc.c
stacktrace.c riscv: stacktrace: fixed walk_stackframe() 2024-05-22 16:12:49 -07:00
suspend.c riscv: Do not save the scratch CSR during suspend 2024-04-28 14:50:36 -07:00
suspend_entry.S riscv: Use SYM_*() assembly macros instead of deprecated ones 2023-11-06 09:42:47 -08:00
sys_hwprobe.c riscv: hwprobe: export Zihintpause ISA extension 2024-04-28 14:50:38 -07:00
sys_riscv.c riscv: remove unused header 2024-03-27 07:23:23 -07:00
syscall_table.c
time.c RISC-V: paravirt: Add skeleton for pv-time support 2023-12-30 11:25:03 +05:30
traps.c riscv: use KERN_INFO in do_trap 2024-04-04 12:12:14 -07:00
traps_misaligned.c riscv: misaligned: remove CONFIG_RISCV_M_MODE specific code 2024-04-28 14:50:37 -07:00
unaligned_access_speed.c riscv: Use kcalloc() instead of kzalloc() 2024-03-20 08:56:07 -07:00
vdso.c riscv: vdso: Use generic union vdso_data_store 2024-02-20 20:56:00 +01:00
vector.c riscv: vector: allow kernel-mode Vector with preemption 2024-01-16 07:14:02 -08:00
vmcore_info.c crash: split vmcoreinfo exporting code out from crash_core.c 2024-02-23 17:48:22 -08:00
vmlinux-xip.lds.S riscv: Check if the code to patch lies in the exit section 2024-01-09 10:58:59 -08:00
vmlinux.lds.S riscv: Check if the code to patch lies in the exit section 2024-01-09 10:58:59 -08:00