diff --git a/arch/arm64/kernel/cpu.c b/arch/arm64/kernel/cpu.c index 5ba95027..fa53d20f 100644 --- a/arch/arm64/kernel/cpu.c +++ b/arch/arm64/kernel/cpu.c @@ -143,6 +143,11 @@ void arch_save_panic_regs(void *irq_regs) clv = get_arm64_this_cpu_local(); + /* If kernel mode PF occurred, unroll the causing call stack */ + if (cpu_local_var(kernel_mode_pf_regs)) { + regs = cpu_local_var(kernel_mode_pf_regs); + } + /* For user-space, use saved kernel context */ if (regs->pc < USER_END) { memset(clv->arm64_cpu_local_thread.panic_regs, diff --git a/kernel/include/cls.h b/kernel/include/cls.h index 3ba98905..ec0c3ab5 100644 --- a/kernel/include/cls.h +++ b/kernel/include/cls.h @@ -79,6 +79,7 @@ struct cpu_local_var { ihk_spinlock_t runq_lock; unsigned long runq_irqstate; struct thread *current; + void *kernel_mode_pf_regs; int prevpid; struct list_head runq; size_t runq_len; diff --git a/kernel/mem.c b/kernel/mem.c index 8bb1b771..9483e5eb 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -1323,6 +1323,7 @@ static void unhandled_page_fault(struct thread *thread, void *fault_addr, ihk_mc_debug_show_interrupt_context(regs); if (!(reason & PF_USER)) { + cpu_local_var(kernel_mode_pf_regs) = regs; panic("panic: kernel mode PF"); }