linux-stable/arch/riscv
Changbin Du 71f46f3d1b riscv: eliminate unreliable __builtin_frame_address(1)
commit 6a00ef4493 upstream.

I tried different pieces of code which uses __builtin_frame_address(1)
(with both gcc version 7.5.0 and 10.3.0) to verify whether it works as
expected on riscv64. The result is negative.

What the compiler had generated is as below:
31                      fp = (unsigned long)__builtin_frame_address(1);
   0xffffffff80006024 <+200>:   ld      s1,0(s0)

It takes '0(s0)' as the address of frame 1 (caller), but the actual address
should be '-16(s0)'.

          |       ...       | <-+
          +-----------------+   |
          | return address  |   |
          | previous fp     |   |
          | saved registers |   |
          | local variables |   |
  $fp --> |       ...       |   |
          +-----------------+   |
          | return address  |   |
          | previous fp --------+
          | saved registers |
  $sp --> | local variables |
          +-----------------+

This leads the kernel can not dump the full stack trace on riscv.

[    7.222126][    T1] Call Trace:
[    7.222804][    T1] [<ffffffff80006058>] dump_backtrace+0x2c/0x3a

This problem is not exposed on most riscv builds just because the '0(s0)'
occasionally is the address frame 2 (caller's caller), if only ra and fp
are stored in frame 1 (caller).

          |       ...       | <-+
          +-----------------+   |
          | return address  |   |
  $fp --> | previous fp     |   |
          +-----------------+   |
          | return address  |   |
          | previous fp --------+
          | saved registers |
  $sp --> | local variables |
          +-----------------+

This could be a *bug* of gcc that should be fixed. But as noted in gcc
manual "Calling this function with a nonzero argument can have
unpredictable effects, including crashing the calling program.", let's
remove the '__builtin_frame_address(1)' in backtrace code.

With this fix now it can show full stack trace:
[   10.444838][    T1] Call Trace:
[   10.446199][    T1] [<ffffffff8000606c>] dump_backtrace+0x2c/0x3a
[   10.447711][    T1] [<ffffffff800060ac>] show_stack+0x32/0x3e
[   10.448710][    T1] [<ffffffff80a005c0>] dump_stack_lvl+0x58/0x7a
[   10.449941][    T1] [<ffffffff80a005f6>] dump_stack+0x14/0x1c
[   10.450929][    T1] [<ffffffff804c04ee>] ubsan_epilogue+0x10/0x5a
[   10.451869][    T1] [<ffffffff804c092e>] __ubsan_handle_load_invalid_value+0x6c/0x78
[   10.453049][    T1] [<ffffffff8018f834>] __pagevec_release+0x62/0x64
[   10.455476][    T1] [<ffffffff80190830>] truncate_inode_pages_range+0x132/0x5be
[   10.456798][    T1] [<ffffffff80190ce0>] truncate_inode_pages+0x24/0x30
[   10.457853][    T1] [<ffffffff8045bb04>] kill_bdev+0x32/0x3c
...

Signed-off-by: Changbin Du <changbin.du@gmail.com>
Fixes: eac2f3059e ("riscv: stacktrace: fix the riscv stacktrace when CONFIG_FRAME_POINTER enabled")
Cc: stable@vger.kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-02-16 12:56:18 +01:00
..
boot riscv: dts: microchip: mpfs: Drop empty chosen node 2022-01-27 11:05:28 +01:00
configs riscv: Get rid of MAXPHYSMEM configs 2022-01-27 11:02:49 +01:00
errata riscv: skip errata_cip_453.o if CONFIG_ERRATA_SIFIVE_CIP_453 is disabled 2021-06-01 21:16:41 -07:00
include RISC-V: Use common riscv_cpuid_to_hartid_mask() for both SMP=y and SMP=n 2022-01-27 11:02:50 +01:00
kernel riscv: eliminate unreliable __builtin_frame_address(1) 2022-02-16 12:56:18 +01:00
lib riscv: __asm_copy_to-from_user: Fix: Typos in comments 2021-07-23 17:49:12 -07:00
mm riscv: mm: fix wrong phys_ram_base value for RV64 2022-01-27 11:02:50 +01:00
net riscv, bpf: Fix potential NULL dereference 2021-10-28 08:14:30 -07:00
Kbuild riscv: Allow device trees to be built into the kernel 2020-05-18 11:38:05 -07:00
Kconfig riscv: Get rid of MAXPHYSMEM configs 2022-01-27 11:02:49 +01:00
Kconfig.debug RISC-V: Remove EARLY_PRINTK support 2018-12-17 10:23:46 -08:00
Kconfig.erratas riscv: enable SiFive errata CIP-453 and CIP-1200 Kconfig only if CONFIG_64BIT=y 2021-05-06 09:40:13 -07:00
Kconfig.socs riscv: sifive: fix Kconfig errata warning 2021-06-12 17:20:50 -07:00
Makefile riscv: fix build with binutils 2.38 2022-02-16 12:56:17 +01:00