diff options
| author | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2024-05-28 23:21:34 +0300 |
|---|---|---|
| committer | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2024-05-28 23:21:34 +0300 |
| commit | f73a058be5d70dd81a43f16b2bbff4b1576a7af8 (patch) | |
| tree | b7959c01cf7a5d95c7c4d5b61929ff9123370322 /arch/riscv/kernel/stacktrace.c | |
| parent | 6cb05d89fd62a76a9b74bd16211fb0930e89fea8 (diff) | |
| parent | 3e049b6b8f32f25c6967f4cffd8eac6e1e5316f6 (diff) | |
| download | linux-f73a058be5d70dd81a43f16b2bbff4b1576a7af8.tar.xz | |
Merge remote-tracking branch 'drm/drm-fixes' into drm-misc-fixes
v6.10-rc1 is released, forward from v6.9
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Diffstat (limited to 'arch/riscv/kernel/stacktrace.c')
| -rw-r--r-- | arch/riscv/kernel/stacktrace.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c index 64a9c093aef9..528ec7cc9a62 100644 --- a/arch/riscv/kernel/stacktrace.c +++ b/arch/riscv/kernel/stacktrace.c @@ -18,6 +18,16 @@ 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)(void *, unsigned long), void *arg) { @@ -41,21 +51,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) || (level++ >= 0 && !fn(arg, pc)))) 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 { |
