diff options
| author | Peter Zijlstra <peterz@infradead.org> | 2024-07-04 16:00:24 +0200 |
|---|---|---|
| committer | Peter Zijlstra <peterz@infradead.org> | 2024-07-04 16:00:24 +0200 |
| commit | 0c8ea05e9b3d8e5287e2a968f2a2e744dfd31b99 (patch) | |
| tree | ba0443b74f063471c5d81d85e795e04e7e1dc79c /arch/riscv/kernel/stacktrace.c | |
| parent | 0ca4da2412da05fb9dd0b5d90dcc8026219f0f29 (diff) | |
| parent | 34b3fc558b537bdf99644dcde539e151716f6331 (diff) | |
| download | linux-0c8ea05e9b3d8e5287e2a968f2a2e744dfd31b99.tar.gz linux-0c8ea05e9b3d8e5287e2a968f2a2e744dfd31b99.zip | |
Merge branch 'tip/x86/cpu'
The Lunarlake patches rely on the new VFM stuff.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
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 { |
