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