Skip to content

Commit 055c7e7

Browse files
seehearfeelchenhuacai
authored andcommitted
LoongArch: Handle percpu handler address for ORC unwinder
After commit 4cd641a ("LoongArch: Remove unnecessary checks for ORC unwinder"), the system can not boot normally under some configs (such as enable KASAN), there are many error messages "cannot find unwind pc". The kernel boots normally with the defconfig, so no problem found out at the first time. Here is one way to reproduce: cd linux make mrproper defconfig -j"$(nproc)" scripts/config -e KASAN make olddefconfig all -j"$(nproc)" sudo make modules_install sudo make install sudo reboot The address that can not unwind is not a valid kernel address which is between "pcpu_handlers[cpu]" and "pcpu_handlers[cpu] + vec_sz" due to the code of eentry was copied to the new area of pcpu_handlers[cpu] in setup_tlb_handler(), handle this special case to get the valid address to unwind normally. Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent 77403a0 commit 055c7e7

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

arch/loongarch/include/asm/setup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
#define _LOONGARCH_SETUP_H
88

99
#include <linux/types.h>
10+
#include <linux/threads.h>
1011
#include <asm/sections.h>
1112
#include <uapi/asm/setup.h>
1213

1314
#define VECSIZE 0x200
1415

1516
extern unsigned long eentry;
1617
extern unsigned long tlbrentry;
18+
extern unsigned long pcpu_handlers[NR_CPUS];
19+
extern long exception_handlers[VECSIZE * 128 / sizeof(long)];
1720
extern char init_command_line[COMMAND_LINE_SIZE];
1821
extern void tlb_init(int cpu);
1922
extern void cpu_cache_init(void);

arch/loongarch/kernel/unwind_orc.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,22 @@ static inline unsigned long bt_address(unsigned long ra)
352352
{
353353
extern unsigned long eentry;
354354

355+
#if defined(CONFIG_NUMA) && !defined(CONFIG_PREEMPT_RT)
356+
int cpu;
357+
int vec_sz = sizeof(exception_handlers);
358+
359+
for_each_possible_cpu(cpu) {
360+
if (!pcpu_handlers[cpu])
361+
continue;
362+
363+
if (ra >= pcpu_handlers[cpu] &&
364+
ra < pcpu_handlers[cpu] + vec_sz) {
365+
ra = ra + eentry - pcpu_handlers[cpu];
366+
break;
367+
}
368+
}
369+
#endif
370+
355371
if (ra >= eentry && ra < eentry + EXCCODE_INT_END * VECSIZE) {
356372
unsigned long func;
357373
unsigned long type = (ra - eentry) / VECSIZE;

0 commit comments

Comments
 (0)