From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f170.google.com (mail-pf1-f170.google.com [209.85.210.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 11415438463 for ; Tue, 7 Jul 2026 17:24:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.170 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783445082; cv=none; b=WY1l6YYKfM5i7dl2ElU5R2IbvcVhLEFVBBZ66gdGmYF55VpjaQPHi1Kcs2PmQOIdzvVV+llO2lpNP2SFZGlUekyqJBncqKOsfPJYVBx7zocnQHVs1viW4LuDvFmuwFS9pjruWlHlC3NFoOJagK6mFvrhihhE9B7JuPzfC4pcmWo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783445082; c=relaxed/simple; bh=1PXNn6T4TLlK/G7qUvpWY5n0HLwGtFjEJVBZj88BG4c=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=YUXzPz6Lk2x/TsgLTrwjp9AP8JyHErN4+7zGnmYV/MkWEUHTpqt0PecvHJ/V8CWUExPX7jFrRRY5PPpgQiSzyHIKkniYL/PTwYLzFgTJiutSakBLxTBcosI/D5lPYzjxLZvoPgwgWgsF56lIGSnswtNyGDzDu0usfc0G5oMUmfM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kZkjWAeu; arc=none smtp.client-ip=209.85.210.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kZkjWAeu" Received: by mail-pf1-f170.google.com with SMTP id d2e1a72fcca58-847d1e9db22so4928916b3a.2 for ; Tue, 07 Jul 2026 10:24:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783445080; x=1784049880; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=QVbkKIpVgqIdeBkCJKcg7TksfPhMWq9fBiNA2uIiNXc=; b=kZkjWAeuDexlFNZ+e0qYH72fvt/IvKQF2OWFM8pThDEsosBQenWruquMCmR9n7OFu6 ak+G9yOILWlNAcb6HQDegNMFCiw0N8UROebg6YC2H1mmwtQcRX5kkPVMU5e0Veg16X4y ZppLoSTSDH1wtxEaG5rxztJyDHtTz43Pr/p6Oc53Om8t2AnPpDX+g0sHrel9kBqLhiwT r3f9Ue9sduuc4/a2BU6gs7B9UKIMxzkXhXChKyoFHeTrZ4yMyNEYUMBIlNmXbyXo9ogY VbSHgiprm0GJom5ZjJXrKcjkG4XGUYxG/W3z5ZRo5KwShpkP0a9yHFfsXPYkzxpPfNaM /XfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783445080; x=1784049880; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=QVbkKIpVgqIdeBkCJKcg7TksfPhMWq9fBiNA2uIiNXc=; b=Al7SkhwEIe0bGrK00TwaNg+PzV77b+ik7UxzYa9omVnJOiS8cKf3oznZ5rG/+t2JOp XUx/jFcrVE9YR0xcEJxkO+FGxwc14Ng7MxhhFheUT+jgxmmAF7WAChqNmVkofeSX6YJ7 YFYAzB0IP0s4KoJaymH7dr0SYoiOFAfr3DdDyhG5hqBQ531gx2ZGtOvhwTPsp655Uj/d +h8RY1B3ehlOEPgEoMcqXrRDwy+SkJgExt+B8NUATTzZ01B0myANaKkc1CVBibBDKbk+ Xc3nFy+srYLv2O98jWM+PalFVvxyiIqkooGb0oLP1S2K1RxkYgJfdxcfy6/itZu0PVoi CbxA== X-Forwarded-Encrypted: i=1; AHgh+Rqo6jrBqidX/AJHWk+IyelxWhIlKC/oO3KCaRjPIh+oNH0SiTzNHu/QTIKXDjxGRNGBrevWFcTj9CP+FEs=@vger.kernel.org X-Gm-Message-State: AOJu0Yyepcf8/PR7qOiQZMCdDcc4io+/malJ7hnf/Sqz4XC1ZtkySajA 98JaxRrnnSOR3ZOvsRpkLHZLHL+6wkcTT1xs5ixRD5T9fKbxF2B8ofx5 X-Gm-Gg: AfdE7cnot+SAsv9YCYGR9HpC9SjXIEYlVqCTOaeluCqeIcZYW2ZKGZKYj+qvGXToVHl SAmvx693iQZ7moHYffjcZMVyiGGeIUXXVTsjATSGjD2WPgdfXZCUo7w6wRlHB60761xYl2UCQL+ W8NfiliuBIBJmhdJMw/1eEgZ2EBpXBlQrT7fOni1J734I1lqgAsTuGA17PBJca4idjmhn+cHkPn yTnALGOYof9Jx490gIUfwDsPBhBi/WTJztqRHPQPWpyznM64KAvPZyHekqMShJeF8T9Vv3tRCDy b4RVTHM0b3Epys8eac51rtqNTG0/sEVknkUjZnpeSgHW7Z+6P2c/LUWW3gYZSVgxnxBjBghYs7i 297RWCTAhLEb/tF2WOdTwNytoe6chDF6M/KAExaInog1l9Mm7ertqvyskjowzhj6I44LYjyGMDx toEVojrg2kh1YnkKae5/j5n8K65e/U0oKfI3CceeBI47RMbP5uvW/AFt+npoxF/j0GXw== X-Received: by 2002:a05:6a21:50f:b0:3bf:c126:baf7 with SMTP id adf61e73a8af0-3c08ef51a7fmr7588434637.47.1783445079945; Tue, 07 Jul 2026 10:24:39 -0700 (PDT) Received: from li-1a3e774c-28e4-11b2-a85c-acc9f2883e29.ibm.com.com ([106.51.160.236]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659c8665sm10569833c88.10.2026.07.07.10.24.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jul 2026 10:24:39 -0700 (PDT) From: "Mukesh Kumar Chaurasiya (IBM)" To: maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com, chleroy@kernel.org, sshegde@linux.ibm.com, mchauras@linux.ibm.com, mkchauras@gmail.com, ruanjinjie@huawei.com, thuth@redhat.com, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Cc: Andreas Schwab Subject: [PATCH] powerpc/970: fix nap return address corruption on async interrupt exit Date: Tue, 7 Jul 2026 22:54:30 +0530 Message-ID: <20260707172430.790040-1-mkchauras@gmail.com> X-Mailer: git-send-email 2.55.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit On PowerMac G5 (PPC970, CONFIG_PPC_970_NAP) the system panics shortly after boot with symptoms including instruction fetch faults, kernel data access faults, and stack corruption, predominantly on SMP and always somewhere inside softirq processing. The PPC970 idle path works by setting _TLF_NAPPING in the current thread's local flags before entering the MSR_POW nap loop. When any async interrupt wakes the CPU, nap_adjust_return() is expected to detect _TLF_NAPPING, clear it, and rewrite regs->NIP to power4_idle_nap_return so that the interrupt returns cleanly to the caller of power4_idle_nap() rather than back into the nap spin loop. DEFINE_INTERRUPT_HANDLER_ASYNC generates the following sequence: irq_enter_rcu(); ____func(regs); /* timer_interrupt / do_IRQ body */ irq_exit_rcu(); /* softirqs run here, irqs re-enabled */ arch_interrupt_async_exit_prepare(regs); /* nap_adjust_return was here */ irqentry_exit(regs, state); irq_exit_rcu() calls invoke_softirq() -> do_softirq_own_stack(), which runs softirqs with hardware interrupts re-enabled. A nested async interrupt can therefore arrive while _TLF_NAPPING is still set. That nested interrupt reaches nap_adjust_return() in its own arch_interrupt_async_exit_prepare() call, finds _TLF_NAPPING set, and redirects *its own* regs->NIP to power4_idle_nap_return. Returning via that blr with an unrelated LR on the softirq stack jumps to a garbage address, causing the observed crashes. The comment that previously lived in arch_interrupt_async_exit_prepare() even described this exact hazard ("must come before irq_exit()"), but nap_adjust_return() was placed after irq_exit_rcu() in the macro, so the protection was never effective. Fix this by calling nap_adjust_return() inside DEFINE_INTERRUPT_HANDLER_ASYNC immediately before irq_exit_rcu(), ensuring _TLF_NAPPING is cleared and regs->NIP is adjusted before any code that can re-enable interrupts or invoke softirqs runs. Move the explanatory comment into nap_adjust_return() itself and remove it from arch_interrupt_async_exit_prepare(). Fixes: bee25f97ad24 ("powerpc: Enable GENERIC_ENTRY feature") Closes: https://lore.kernel.org/all/87wlvazrdy.fsf@igel.home/ Reported-by: Andreas Schwab Signed-off-by: Mukesh Kumar Chaurasiya (IBM) --- arch/powerpc/include/asm/entry-common.h | 15 +++++++-------- arch/powerpc/include/asm/interrupt.h | 1 + 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/include/asm/entry-common.h b/arch/powerpc/include/asm/entry-common.h index fc636c42e89a..c5adb5006361 100644 --- a/arch/powerpc/include/asm/entry-common.h +++ b/arch/powerpc/include/asm/entry-common.h @@ -66,6 +66,13 @@ static inline void srr_regs_clobbered(void) static inline void nap_adjust_return(struct pt_regs *regs) { #ifdef CONFIG_PPC_970_NAP + /* + * Adjust the nap return address before irq_exit_rcu(). irq_exit_rcu() + * may invoke softirqs with interrupts re-enabled, allowing a nested + * async interrupt to arrive. If _TLF_NAPPING is still set at that + * point, the nested interrupt would erroneously redirect its own + * return address to power4_idle_nap_return, corrupting the stack. + */ if (unlikely(test_thread_local_flags(_TLF_NAPPING))) { /* Can avoid a test-and-clear because NMIs do not call this */ clear_thread_local_flags(_TLF_NAPPING); @@ -286,14 +293,6 @@ static inline void arch_interrupt_async_enter_prepare(struct pt_regs *regs) static inline void arch_interrupt_async_exit_prepare(struct pt_regs *regs) { - /* - * Adjust at exit so the main handler sees the true NIA. This must - * come before irq_exit() because irq_exit can enable interrupts, and - * if another interrupt is taken before nap_adjust_return has run - * here, then that interrupt would return directly to idle nap return. - */ - nap_adjust_return(regs); - arch_interrupt_exit_prepare(regs); } diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h index fb42a664ae54..1b45a49e9bed 100644 --- a/arch/powerpc/include/asm/interrupt.h +++ b/arch/powerpc/include/asm/interrupt.h @@ -246,6 +246,7 @@ interrupt_handler void func(struct pt_regs *regs) \ instrumentation_begin(); \ irq_enter_rcu(); \ ____##func (regs); \ + nap_adjust_return(regs); \ irq_exit_rcu(); \ instrumentation_end(); \ arch_interrupt_async_exit_prepare(regs); \ -- 2.55.0