Accessing thread_info flags can cause an SLB fault, so it must not be done with MSR[RI]=0, which leads to SLB unrecoverable fault error.
Signed-off-by: Nicholas Piggin <npig...@gmail.com> --- arch/powerpc/kernel/syscall_64.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c index 87d95b455b83..a56ae78f2d1d 100644 --- a/arch/powerpc/kernel/syscall_64.c +++ b/arch/powerpc/kernel/syscall_64.c @@ -313,12 +313,18 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign { unsigned long *ti_flagsp = ¤t_thread_info()->flags; unsigned long flags; + unsigned long ret = 0; if (IS_ENABLED(CONFIG_PPC_BOOK3S) && unlikely(!(regs->msr & MSR_RI))) unrecoverable_exception(regs); BUG_ON(regs->msr & MSR_PR); BUG_ON(!FULL_REGS(regs)); + if (unlikely(*ti_flagsp & _TIF_EMULATE_STACK_STORE)) { + clear_bits(_TIF_EMULATE_STACK_STORE, ti_flagsp); + ret = 1; + } + local_irq_save(flags); if (regs->softe == IRQS_ENABLED) { @@ -370,10 +376,6 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign */ kuap_restore_amr(regs); - if (unlikely(*ti_flagsp & _TIF_EMULATE_STACK_STORE)) { - clear_bits(_TIF_EMULATE_STACK_STORE, ti_flagsp); - return 1; - } - return 0; + return ret; } #endif -- 2.23.0