diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index f747eacd0a6521813c39ae11751428d2530ea5bb..691bf629710f7806a9b66249b1f72f4ee91fdbf0 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -1574,6 +1574,9 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs) static bool arm64_do_kernel_sea(void __user *addr, unsigned int esr, struct pt_regs *regs, int sig, int code) { + u64 orig_pc = regs->pc; + int err; + if (!IS_ENABLED(CONFIG_ARCH_HAS_UACCESS_MCSAFE)) return false; @@ -1583,14 +1586,24 @@ static bool arm64_do_kernel_sea(void __user *addr, unsigned int esr, if (user_mode(regs)) return false; - if (apei_claim_sea(regs) < 0) - return false; - if (!fixup_exception_mc(regs)) return false; - if (current->flags & PF_KTHREAD) + err = apei_claim_sea(regs); + if (err) { + pr_emerg( + "comm: %s pid: %d apei claim sea failed. addr: %#lx, esr: %#x\n", + current->comm, current->pid, (unsigned long)addr, esr); + } + + if (!current->mm) { + if (err) { + regs->pc = orig_pc; + return false; + } + return true; + } set_thread_esr(0, esr); arm64_force_sig_fault(sig, code, addr,