summaryrefslogtreecommitdiff
path: root/arch/loongarch/kernel/unwind_orc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/loongarch/kernel/unwind_orc.c')
-rw-r--r--arch/loongarch/kernel/unwind_orc.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/loongarch/kernel/unwind_orc.c b/arch/loongarch/kernel/unwind_orc.c
index 8a6e3429a860..9cfb5bb1991f 100644
--- a/arch/loongarch/kernel/unwind_orc.c
+++ b/arch/loongarch/kernel/unwind_orc.c
@@ -350,7 +350,21 @@ EXPORT_SYMBOL_GPL(unwind_start);
static inline unsigned long bt_address(unsigned long ra)
{
- extern unsigned long eentry;
+#if defined(CONFIG_NUMA) && !defined(CONFIG_PREEMPT_RT)
+ int cpu;
+ int vec_sz = sizeof(exception_handlers);
+
+ for_each_possible_cpu(cpu) {
+ if (!pcpu_handlers[cpu])
+ continue;
+
+ if (ra >= pcpu_handlers[cpu] &&
+ ra < pcpu_handlers[cpu] + vec_sz) {
+ ra = ra + eentry - pcpu_handlers[cpu];
+ break;
+ }
+ }
+#endif
if (ra >= eentry && ra < eentry + EXCCODE_INT_END * VECSIZE) {
unsigned long func;
@@ -494,7 +508,7 @@ bool unwind_next_frame(struct unwind_state *state)
state->pc = bt_address(pc);
if (!state->pc) {
- pr_err("cannot find unwind pc at %p\n", (void *)pc);
+ pr_err("cannot find unwind pc at %px\n", (void *)pc);
goto err;
}