linux/arch/riscv
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
..
boot riscv: make image compression configurable 2024-05-22 16:12:44 -07:00
configs RISC-V Patches for the 6.10 Merge Window, Part 1 2024-05-22 09:56:00 -07:00
crypto crypto: riscv - add vector crypto accelerated AES-CBC-CTS 2024-03-20 08:56:11 -07:00
errata RISC-V Patches for the 6.10 Merge Window, Part 1 2024-05-22 09:56:00 -07:00
include ftrace: riscv: move from REGS to ARGS 2024-05-22 16:12:48 -07:00
kernel riscv: stacktrace: fixed walk_stackframe() 2024-05-22 16:12:49 -07:00
kvm Kbuild updates for v6.10 2024-05-18 12:39:20 -07:00
lib RISC-V Patches for the 6.9 Merge Window 2024-03-22 10:41:13 -07:00
mm RISC-V Patches for the 6.10 Merge Window, Part 1 2024-05-22 09:56:00 -07:00
net Modules changes for v6.10-rc1 2024-05-15 14:05:08 -07:00
purgatory Makefile: remove redundant tool coverage variables 2024-05-14 23:35:48 +09:00
tools riscv: Check relocations at compile time 2023-04-19 07:46:32 -07:00
Kbuild RISC-V: hook new crypto subdir into build-system 2024-01-22 17:55:17 -08:00
Kconfig ftrace: riscv: move from REGS to ARGS 2024-05-22 16:12:48 -07:00
Kconfig.debug riscv: Add tests for riscv module loading 2023-11-07 14:59:32 -08:00
Kconfig.errata riscv: thead: Rename T-Head PBMT to MAE 2024-04-25 10:22:33 -07:00
Kconfig.socs RISC-V: drop SOC_VIRT for ARCH_VIRT 2024-04-10 11:37:50 +01:00
Makefile riscv: show help string for riscv-specific targets 2024-05-22 16:12:45 -07:00
Makefile.postlink kbuild: remove ARCH_POSTLINK from module builds 2023-10-28 21:10:08 +09:00