lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260125164016.331257-4-qq570070308@gmail.com>
Date: Mon, 26 Jan 2026 00:40:10 +0800
From: Xie Yuanbin <qq570070308@...il.com>
To: linux@...linux.org.uk,
	johannes@...solutions.net,
	masahiroy@...nel.org,
	jgross@...e.com,
	nsc@...nel.org,
	kees@...nel.org,
	tglx@...nel.org,
	mingo@...nel.org,
	frederic@...nel.org,
	paulmck@...nel.org,
	peterz@...radead.org,
	mathieu.desnoyers@...icios.com,
	luto@...nel.org,
	edumazet@...gle.com
Cc: linux-arm-kernel@...ts.infradead.org,
	linux-kernel@...r.kernel.org,
	Xie Yuanbin <qq570070308@...il.com>
Subject: [PATCH 3/9] ARM: entry: fix wrong lockdep hardirqs state

When CONFIG_PROVE_LOCKING=y, CONFIG_TRACE_IRQFLAGS=y, CONFIG_NO_HZ_FULL=y,
and nohz_full is correctly enabled, if a user program returns to user mode
on the nohz_full CPUs, the following WARNING will be triggered:
```log
[    4.763050] ------------[ cut here ]------------
[    4.763244] WARNING: kernel/context_tracking.c:450 at __ct_user_enter+0x180/0x184, CPU#0: bash/1
[    4.764815] Modules linked in:
[    4.765386] CPU: 0 UID: 0 PID: 1 Comm: bash Not tainted 6.19.0-rc6-next-20260123 #1 VOLUNTARY
[    4.765761] Hardware name: Generic DT based system
[    4.766105] Call trace:
[    4.766151]  unwind_backtrace from show_stack+0x10/0x14
[    4.766686]  show_stack from dump_stack_lvl+0x68/0x80
[    4.766919]  dump_stack_lvl from __warn+0xf0/0x270
[    4.767140]  __warn from warn_slowpath_fmt+0xc0/0x194
[    4.767542]  warn_slowpath_fmt from __ct_user_enter+0x180/0x184
[    4.767792]  __ct_user_enter from user_enter_callable+0x64/0x6c
[    4.768105]  user_enter_callable from no_work_pending+0x8/0x4c
[    4.768415] Exception stack(0xf0849fb0 to 0xf0849ff8)
[    4.768816] 9fa0:                                     00000000 00000000 00000000 00000000
[    4.769060] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    4.769335] 9fe0: 00000000 beaf2ef0 00000000 b6f10dec 00000010 00000000
[    4.769669] irq event stamp: 211021
[    4.770932] hardirqs last  enabled at (211021): [<c0300114>] no_work_pending+0x4/0x4c
[    4.771687] hardirqs last disabled at (211020): [<c032a064>] do_work_pending+0x48/0xa4
[    4.772290] softirqs last  enabled at (210994): [<c0371354>] handle_softirqs+0x434/0x4dc
[    4.772902] softirqs last disabled at (210987): [<c0371654>] __irq_exit_rcu+0xd0/0x204
[    4.773359] ---[ end trace 0000000000000000 ]---
```

In ret_to_user() and ret_fast_syscall(), disable_irq_notrace() is called,
which skips trace_hardirqs_off(). On the other hand,
asm_trace_hardirqs_on() is called prematurely before user_enter(). This
causes lockdep's hardirqs to be recorded as enabled when user_enter() is
called, even if interrupts are disabled.

1. Do not skip the tracing when enabling/disabling interrupts before
returning to user mode, just like what other architectures do.
2. Call asm_trace_hardirqs_on() after user_enter().

Fixes: b04db8e19fc2 ("rcu: Use lockdep to assert IRQs are disabled/enabled")

Signed-off-by: Xie Yuanbin <qq570070308@...il.com>
---
 arch/arm/kernel/entry-common.S | 14 ++++++--------
 arch/arm/kernel/signal.c       |  7 +------
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index f579770fab71..0e462bbede2f 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -71,7 +71,7 @@ __ret_fast_syscall:
 	mov	r0, sp				@ 'regs'
 	bl	do_rseq_syscall
 #endif
-	disable_irq_notrace			@ disable interrupts
+	disable_irq save = 0			@ disable interrupts
 	ldr	r1, [tsk, #TI_FLAGS]		@ re-check for syscall tracing
 	movs	r1, r1, lsl #16
 	beq	no_work_pending
@@ -97,30 +97,28 @@ ENDPROC(ret_fast_syscall)
 
 /*
  * "slow" syscall return path.  "why" tells us if this was a real syscall.
- * IRQs may be enabled here, so always disable them.  Note that we use the
- * "notrace" version to avoid calling into the tracing code unnecessarily.
- * do_work_pending() will update this state if necessary.
+ * IRQs may be enabled here, so always disable them.
  */
 ENTRY(ret_to_user)
 ret_slow_syscall:
 #if IS_ENABLED(CONFIG_DEBUG_RSEQ)
 	/* do_rseq_syscall needs interrupts enabled. */
-	enable_irq_notrace			@ enable interrupts
+	enable_irq save = 0			@ enable interrupts
 	mov	r0, sp				@ 'regs'
 	bl	do_rseq_syscall
 #endif
-	disable_irq_notrace			@ disable interrupts
+	disable_irq save = 0			@ disable interrupts
 ENTRY(ret_to_user_from_irq)
 	ldr	r1, [tsk, #TI_FLAGS]
 	movs	r1, r1, lsl #16
 	bne	slow_work_pending
 no_work_pending:
-	asm_trace_hardirqs_on save = 0
-
 #ifdef CONFIG_CONTEXT_TRACKING_USER
 	bl	user_enter_callable
 #endif
 
+	asm_trace_hardirqs_on save = 0
+
 #ifdef CONFIG_KSTACK_ERASE
 	bl	stackleak_erase_on_task_stack
 #endif
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 79a6730fa0eb..93e0a7637c81 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -601,12 +601,7 @@ static int do_signal(struct pt_regs *regs, int syscall)
 asmlinkage int
 do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 {
-	/*
-	 * The assembly code enters us with IRQs off, but it hasn't
-	 * informed the tracing code of that for efficiency reasons.
-	 * Update the trace code with the current status.
-	 */
-	trace_hardirqs_off();
+	/* The assembly code enters us with IRQs off. */
 	do {
 		if (likely(thread_flags & _TIF_NEED_RESCHED)) {
 			schedule();
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ