+++ /dev/null
-From 937215a95b66766cc984c02d2a9f70d160523364 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 13 Nov 2020 14:42:21 +0800
-Subject: riscv: Cleanup stacktrace
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Kefeng Wang <wangkefeng.wang@huawei.com>
-
-[ Upstream commit 99c168fccbfedbc10ce1cb2dcb9eb790c478d833 ]
-
-1. add asm/stacktrace.h for walk_stackframe and struct stackframe
-2. remove unnecessary blank lines in stacktrace.c
-3. fix warning "no previous prototype for ‘fill_callchain’"
-
-Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
-Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
-Stable-dep-of: a2a4d4a6a0bf ("riscv: stacktrace: fixed walk_stackframe()")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/riscv/include/asm/stacktrace.h | 17 +++++++++++++++++
- arch/riscv/kernel/perf_callchain.c | 10 ++--------
- arch/riscv/kernel/stacktrace.c | 9 ++-------
- 3 files changed, 21 insertions(+), 15 deletions(-)
- create mode 100644 arch/riscv/include/asm/stacktrace.h
-
-diff --git a/arch/riscv/include/asm/stacktrace.h b/arch/riscv/include/asm/stacktrace.h
-new file mode 100644
-index 0000000000000..f09c1e31bde9c
---- /dev/null
-+++ b/arch/riscv/include/asm/stacktrace.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+
-+#ifndef _ASM_RISCV_STACKTRACE_H
-+#define _ASM_RISCV_STACKTRACE_H
-+
-+#include <linux/sched.h>
-+#include <asm/ptrace.h>
-+
-+struct stackframe {
-+ unsigned long fp;
-+ unsigned long ra;
-+};
-+
-+extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
-+ bool (*fn)(unsigned long, void *), void *arg);
-+
-+#endif /* _ASM_RISCV_STACKTRACE_H */
-diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
-index fb02811df7143..8b4bd418b3434 100644
---- a/arch/riscv/kernel/perf_callchain.c
-+++ b/arch/riscv/kernel/perf_callchain.c
-@@ -4,11 +4,7 @@
- #include <linux/perf_event.h>
- #include <linux/uaccess.h>
-
--/* Kernel callchain */
--struct stackframe {
-- unsigned long fp;
-- unsigned long ra;
--};
-+#include <asm/stacktrace.h>
-
- /*
- * Get the return address for a single stackframe and return a pointer to the
-@@ -75,13 +71,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
- fp = user_backtrace(entry, fp, 0);
- }
-
--bool fill_callchain(unsigned long pc, void *entry)
-+static bool fill_callchain(unsigned long pc, void *entry)
- {
- return perf_callchain_store(entry, pc) == 0;
- }
-
--void notrace walk_stackframe(struct task_struct *task,
-- struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg);
- void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
- struct pt_regs *regs)
- {
-diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
-index 9c34735c1e771..cd14309fff0d9 100644
---- a/arch/riscv/kernel/stacktrace.c
-+++ b/arch/riscv/kernel/stacktrace.c
-@@ -12,15 +12,12 @@
- #include <linux/stacktrace.h>
- #include <linux/ftrace.h>
-
-+#include <asm/stacktrace.h>
-+
- register unsigned long sp_in_global __asm__("sp");
-
- #ifdef CONFIG_FRAME_POINTER
-
--struct stackframe {
-- unsigned long fp;
-- unsigned long ra;
--};
--
- void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
- bool (*fn)(unsigned long, void *), void *arg)
- {
-@@ -102,7 +99,6 @@ void notrace walk_stackframe(struct task_struct *task,
-
- #endif /* CONFIG_FRAME_POINTER */
-
--
- static bool print_trace_address(unsigned long pc, void *arg)
- {
- const char *loglvl = arg;
-@@ -136,7 +132,6 @@ unsigned long get_wchan(struct task_struct *task)
- return pc;
- }
-
--
- #ifdef CONFIG_STACKTRACE
-
- static bool __save_trace(unsigned long pc, void *arg, bool nosched)
---
-2.43.0
-
+++ /dev/null
-From 4e43cdd51db17bdafaf21fca0c3b534358c1b481 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 21 May 2024 22:13:13 +0300
-Subject: riscv: stacktrace: fixed walk_stackframe()
-
-From: Matthew Bystrin <dev.mbstr@gmail.com>
-
-[ Upstream commit a2a4d4a6a0bf5eba66f8b0b32502cc20d82715a0 ]
-
-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: f766f77a74f5 ("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>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/riscv/kernel/stacktrace.c | 20 ++++++++++++++------
- 1 file changed, 14 insertions(+), 6 deletions(-)
-
-diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
-index ff877ee3fb942..c38b20caad7cc 100644
---- a/arch/riscv/kernel/stacktrace.c
-+++ b/arch/riscv/kernel/stacktrace.c
-@@ -20,6 +20,16 @@ register unsigned long sp_in_global __asm__("sp");
-
- extern asmlinkage void ret_from_exception(void);
-
-+static inline int fp_is_valid(unsigned long fp, unsigned long sp)
-+{
-+ unsigned long low, high;
-+
-+ low = sp + sizeof(struct stackframe);
-+ high = ALIGN(sp, THREAD_SIZE);
-+
-+ return !(fp < low || fp > high || fp & 0x07);
-+}
-+
- void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
- bool (*fn)(unsigned long, void *), void *arg)
- {
-@@ -42,21 +52,19 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
- }
-
- for (;;) {
-- unsigned long low, high;
- struct stackframe *frame;
-
- if (unlikely(!__kernel_text_address(pc) || fn(pc, arg)))
- break;
-
-- /* Validate frame pointer */
-- low = sp + sizeof(struct stackframe);
-- high = ALIGN(sp, THREAD_SIZE);
-- if (unlikely(fp < low || fp > high || fp & 0x7))
-+ if (unlikely(!fp_is_valid(fp, sp)))
- break;
-+
- /* Unwind stack frame */
- frame = (struct stackframe *)fp - 1;
- sp = fp;
-- if (regs && (regs->epc == pc) && (frame->fp & 0x7)) {
-+ if (regs && (regs->epc == pc) && fp_is_valid(frame->ra, sp)) {
-+ /* We hit function where ra is not saved on the stack */
- fp = frame->ra;
- pc = regs->ra;
- } else {
---
-2.43.0
-
+++ /dev/null
-From 0e9e6af8571bcc141fed0f560a07a33c19abf1ce Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 9 Nov 2022 01:49:37 -0500
-Subject: riscv: stacktrace: Make walk_stackframe cross pt_regs frame
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ Upstream commit 7ecdadf7f8c659524f6b2aebf6be7bf619764d90 ]
-
-The current walk_stackframe with FRAME_POINTER would stop unwinding at
-ret_from_exception:
- BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1518
- in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 1, name: init
- CPU: 0 PID: 1 Comm: init Not tainted 5.10.113-00021-g15c15974895c-dirty #192
- Call Trace:
- [<ffffffe0002038c8>] walk_stackframe+0x0/0xee
- [<ffffffe000aecf48>] show_stack+0x32/0x4a
- [<ffffffe000af1618>] dump_stack_lvl+0x72/0x8e
- [<ffffffe000af1648>] dump_stack+0x14/0x1c
- [<ffffffe000239ad2>] ___might_sleep+0x12e/0x138
- [<ffffffe000239aec>] __might_sleep+0x10/0x18
- [<ffffffe000afe3fe>] down_read+0x22/0xa4
- [<ffffffe000207588>] do_page_fault+0xb0/0x2fe
- [<ffffffe000201b80>] ret_from_exception+0x0/0xc
-
-The optimization would help walk_stackframe cross the pt_regs frame and
-get more backtrace of debug info:
- BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1518
- in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 1, name: init
- CPU: 0 PID: 1 Comm: init Not tainted 5.10.113-00021-g15c15974895c-dirty #192
- Call Trace:
- [<ffffffe0002038c8>] walk_stackframe+0x0/0xee
- [<ffffffe000aecf48>] show_stack+0x32/0x4a
- [<ffffffe000af1618>] dump_stack_lvl+0x72/0x8e
- [<ffffffe000af1648>] dump_stack+0x14/0x1c
- [<ffffffe000239ad2>] ___might_sleep+0x12e/0x138
- [<ffffffe000239aec>] __might_sleep+0x10/0x18
- [<ffffffe000afe3fe>] down_read+0x22/0xa4
- [<ffffffe000207588>] do_page_fault+0xb0/0x2fe
- [<ffffffe000201b80>] ret_from_exception+0x0/0xc
- [<ffffffe000613c06>] riscv_intc_irq+0x1a/0x72
- [<ffffffe000201b80>] ret_from_exception+0x0/0xc
- [<ffffffe00033f44a>] vma_link+0x54/0x160
- [<ffffffe000341d7a>] mmap_region+0x2cc/0x4d0
- [<ffffffe000342256>] do_mmap+0x2d8/0x3ac
- [<ffffffe000326318>] vm_mmap_pgoff+0x70/0xb8
- [<ffffffe00032638a>] vm_mmap+0x2a/0x36
- [<ffffffe0003cfdde>] elf_map+0x72/0x84
- [<ffffffe0003d05f8>] load_elf_binary+0x69a/0xec8
- [<ffffffe000376240>] bprm_execve+0x246/0x53a
- [<ffffffe00037786c>] kernel_execve+0xe8/0x124
- [<ffffffe000aecdf2>] run_init_process+0xfa/0x10c
- [<ffffffe000aece16>] try_to_run_init_process+0x12/0x3c
- [<ffffffe000afa920>] kernel_init+0xb4/0xf8
- [<ffffffe000201b80>] ret_from_exception+0x0/0xc
-
-Here is the error injection test code for the above output:
- drivers/irqchip/irq-riscv-intc.c:
- static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
- {
- unsigned long cause = regs->cause & ~CAUSE_IRQ_FLAG;
-+ u32 tmp; __get_user(tmp, (u32 *)0);
-
-Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
-Signed-off-by: Guo Ren <guoren@kernel.org>
-Link: https://lore.kernel.org/r/20221109064937.3643993-3-guoren@kernel.org
-[Palmer: use SYM_CODE_*]
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Stable-dep-of: a2a4d4a6a0bf ("riscv: stacktrace: fixed walk_stackframe()")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/riscv/kernel/entry.S | 3 ++-
- arch/riscv/kernel/stacktrace.c | 9 +++++++++
- 2 files changed, 11 insertions(+), 1 deletion(-)
-
-diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
-index 5214c578a6023..88bd7e5f74cee 100644
---- a/arch/riscv/kernel/entry.S
-+++ b/arch/riscv/kernel/entry.S
-@@ -218,7 +218,7 @@ ret_from_syscall_rejected:
- andi t0, t0, _TIF_SYSCALL_WORK
- bnez t0, handle_syscall_trace_exit
-
--ret_from_exception:
-+SYM_CODE_START_NOALIGN(ret_from_exception)
- REG_L s0, PT_STATUS(sp)
- csrc CSR_STATUS, SR_IE
- #ifdef CONFIG_TRACE_IRQFLAGS
-@@ -232,6 +232,7 @@ ret_from_exception:
- andi s0, s0, SR_SPP
- #endif
- bnez s0, resume_kernel
-+SYM_CODE_END(ret_from_exception)
-
- resume_userspace:
- /* Interrupts must be disabled here so flags are checked atomically */
-diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
-index cd14309fff0d9..ff877ee3fb942 100644
---- a/arch/riscv/kernel/stacktrace.c
-+++ b/arch/riscv/kernel/stacktrace.c
-@@ -18,6 +18,8 @@ register unsigned long sp_in_global __asm__("sp");
-
- #ifdef CONFIG_FRAME_POINTER
-
-+extern asmlinkage void ret_from_exception(void);
-+
- void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
- bool (*fn)(unsigned long, void *), void *arg)
- {
-@@ -61,6 +63,13 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
- fp = frame->fp;
- pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
- &frame->ra);
-+ if (pc == (unsigned long)ret_from_exception) {
-+ if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
-+ break;
-+
-+ pc = ((struct pt_regs *)sp)->epc;
-+ fp = ((struct pt_regs *)sp)->s0;
-+ }
- }
-
- }
---
-2.43.0
-
openvswitch-set-the-skbuff-pkt_type-for-proper-pmtud.patch
arm64-asm-bug-add-.align-2-to-the-end-of-__bug_entry.patch
virtio-delete-vq-in-vp_find_vqs_msix-when-request_ir.patch
-riscv-cleanup-stacktrace.patch
-riscv-stacktrace-make-walk_stackframe-cross-pt_regs-.patch
-riscv-stacktrace-fixed-walk_stackframe.patch
net-fec-avoid-lock-evasion-when-reading-pps_enable.patch
tls-fix-missing-memory-barrier-in-tls_init.patch
nfc-nci-fix-kcov-check-in-nci_rx_work.patch