From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed, 29 Oct 2025 11:22:29 +0100 Subject: [PATCH v2 1/5] ARM: mm: fault: Move harden_branch_predictor() before interrupts are enabled In the LPAE case, interrupts are enabled early in do_page_fault(). If the user attempts to access a pointer > TASK_SIZE then is invoked harden_branch_predictor(). The function will complain that CPU migration is enabled due to its smp_processor_id() usage. The intention is invoke harden_branch_predictor() on the CPU which triggered the page fault. It is only invoked for user access of pointer > TASK_SIZE. This always generate a fault for the user because this area is restricted to the kernel. Move the invocation of harden_branch_predictor() up in the call chain to the two callers do_bad_area() and do_page_fault(). Invoke it if the user accesses the >= TASK_SIZE area. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- arch/arm/mm/fault.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) @ arch/arm/mm/fault.c:186 @ static void { struct task_struct *tsk = current; - if (addr > TASK_SIZE) - harden_branch_predictor(); - #ifdef CONFIG_DEBUG_USER if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) || ((user_debug & UDBG_BUS) && (sig == SIGBUS))) { @ arch/arm/mm/fault.c:218 @ void do_bad_area(unsigned long addr, uns * If we are in kernel mode at this point, we * have no context to handle this fault with. */ - if (user_mode(regs)) + if (user_mode(regs)) { + if (addr >= TASK_SIZE) + harden_branch_predictor(); __do_user_fault(addr, fsr, SIGSEGV, SEGV_MAPERR, regs); - else + } else { __do_kernel_fault(mm, addr, fsr, regs); + } } #ifdef CONFIG_MMU @ arch/arm/mm/fault.c:277 @ do_page_fault(unsigned long addr, unsign /* Enable interrupts if they were enabled in the parent context. */ - if (interrupts_enabled(regs)) + if (interrupts_enabled(regs)) { + if (user_mode(regs) && addr >= TASK_SIZE) + harden_branch_predictor(); local_irq_enable(); + } /* * If we're in an interrupt or have no user