From: Russell King (Oracle) Date: Fri, 5 Dec 2025 12:17:00 +0000 (+0000) Subject: ARM: ensure interrupts are enabled in __do_user_fault() X-Git-Tag: v7.1-rc1~8^2~1^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=59e4f3b45b96a24fc9b7a89e5f8a2168b30f95af;p=thirdparty%2Flinux.git ARM: ensure interrupts are enabled in __do_user_fault() __do_user_fault() may be called from fault handling paths where the interrupts are enabled or disabled. E.g. do_page_fault() calls this with interrupts enabled, whereas do_sect_fault()->do_bad_area() will call this with interrupts disabled. Since this is a userspace fault, we know that interrupts were enabled in the parent context, so call local_irq_enable() here to give a consistent interrupt state. This is necessary for force_sig_info() when PREEMPT_RT is enabled. Reported-by: Yadi.hu Reviewed-by: Sebastian Andrzej Siewior Signed-off-by: Russell King (Oracle) --- diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index ed4330cc3f4e6..6c27ebd490938 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -190,7 +190,8 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, /* * Something tried to access memory that isn't in our memory map.. - * User mode accesses just cause a SIGSEGV + * User mode accesses just cause a SIGSEGV. Ensure interrupts are enabled + * for preempt RT. */ static void __do_user_fault(unsigned long addr, unsigned int fsr, unsigned int sig, @@ -198,6 +199,8 @@ __do_user_fault(unsigned long addr, unsigned int fsr, unsigned int sig, { struct task_struct *tsk = current; + local_irq_enable(); + #ifdef CONFIG_DEBUG_USER if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) || ((user_debug & UDBG_BUS) && (sig == SIGBUS))) { @@ -268,6 +271,7 @@ do_kernel_address_page_fault(struct mm_struct *mm, unsigned long addr, * should not be faulting in kernel space, which includes the * vector/khelper page. Handle the branch predictor hardening * while interrupts are still disabled, then send a SIGSEGV. + * Note that __do_user_fault() will enable interrupts. */ harden_branch_predictor(); __do_user_fault(addr, fsr, SIGSEGV, SEGV_MAPERR, regs);