From: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>,
Venkat Rao Bagalkote <venkat88@linux.ibm.com>,
linux-kernel@vger.kernel.org, chleroy@kernel.org,
Michael Ellerman <mpe@ellerman.id.au>,
Nicholas Piggin <npiggin@gmail.com>,
Hari Bathini <hbathini@linux.ibm.com>,
"Ritesh Harjani (IBM)" <ritesh.list@gmail.com>,
stable@vger.kernel.org,
Josef Schlehofer <pepe.schlehofer@gmail.com>
Subject: [PATCH] powerpc/code-patching: Flush the patch area TLB entry locally
Date: Tue, 3 Nov 2026 08:24:43 +0530 [thread overview]
Message-ID: <b7916dadd8ef56d417d0cbf69fa9ef2a447a5a3e.1793674111.git.ritesh.list@gmail.com> (raw)
patching functions like patch_mem() and patch_instructions(), maps the
target page at the per-cpu text_poke_area, write it, clear the PTE and
then flushes the tlb using flush_tlb_kernel_range(), with interrupts
disabled. flush_tlb_kernel_range() on SMP nohash (e500) does an IPI
based TLB invalidation i.e -
smp_call_function(do_flush_tlb_mm_ipi, NULL, 1);
...which will wait for other CPUs but with interrupts off. This can be
caught by lockdep with the following warning:
WARNING: kernel/smp.c:917 at smp_call_function_many_cond+0x430/0x818, CPU#1: swapper/0/1
CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 7.3.0-rc1-leds-v4 #1 PREEMPT
Hardware name: Turris 1.1 e500v2 0x80211051 Freescale P2020
Call Trace:
[c1915bc0] [c001be04] flush_tlb_kernel_range+0x2c/0x74
[c1915bd0] [c001ce2c] patch_instructions+0x1b0/0x318
[c1915c20] [c003113c] bpf_arch_text_copy+0x5c/0xb4
[c1915c40] [c01c3398] bpf_jit_binary_pack_finalize+0x28/0x8c
[c1915c60] [c0031770] bpf_int_jit_compile+0x5dc/0x758
...
[c1915dd0] [c102e114] ptp_classifier_init+0x30/0x4c
[c1915df0] [c102d3a8] sock_init+0xc8/0xe4
...
hardirqs last disabled at (3076): [<c001ceb4>] patch_instructions+0x238/0x318
Josef confirmed that this was causing a hang (deadlock):
I think this is why the CZ.NIC Turris 1.1 hangs early in boot with
CONFIG_JUMP_LABEL=y. On 6.18.44 it hung in 19 of 19 boots and booted
fine 9 of 9 times with jump labels off. The hang comes while static
keys are patched and modules are loaded, nothing is printed and the
watchdog resets the board. OpenWrt keeps jump labels off on these
boards for now.
...which is possible if both cpus are doing similar operations with interrupts
off and doing TLB invalidation using IPI.
Broadcast TLB invalidation is not needed here since text_poke_area is
a per-cpu area. It is mapped and unmapped with interrupts disabled by
it's own cpu. The only reason I think, if we would need a broadcast tlb
invalidate is, when we want to prevent a stray or malicious write to
this cpu text_poke_area by another CPU. This generally gets solved with
temporary-mm path like how Radix and even x86 implements. However, booke
doesn't implement that, so for now let's ensure we use local tlb
flushing for correctness.
Fixes: 49e3d8ea6248 ("powerpc/fsl_booke: Enable STRICT_KERNEL_RWX")
Cc: stable@vger.kernel.org
Reported-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
Closes: https://lore.kernel.org/all/20261026195644.16384-1-pepe.schlehofer@gmail.com/
Tested-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/lib/code-patching.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 44ff9f684bef..6351342fa5c3 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -276,6 +276,23 @@ static int __do_patch_mem_mm(void *addr, unsigned long val, bool is_dword)
return err;
}
+/*
+ * The patch area is per-CPU and only used by its own CPU, with IRQs
+ * disabled, so only the local TLB can hold an entry for it.
+ *
+ * On nohash SMP, flush_tlb_kernel_range() IPIs the other CPUs and waits, which
+ * must not be done with IRQs disabled (see smp_call_function_many_cond()), so
+ * flush just the local kernel (PID 0) entry.
+ * Book3S keeps flush_tlb_kernel_range() which doesn't IPI here.
+ */
+static void flush_patch_area(unsigned long addr)
+{
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S))
+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+ else
+ local_flush_tlb_page(NULL, addr);
+}
+
static int __do_patch_mem(void *addr, unsigned long val, bool is_dword)
{
int err;
@@ -296,7 +313,7 @@ static int __do_patch_mem(void *addr, unsigned long val, bool is_dword)
err = __patch_mem(addr, val, patch_addr, is_dword);
pte_clear(&init_mm, text_poke_addr, pte);
- flush_tlb_kernel_range(text_poke_addr, text_poke_addr + PAGE_SIZE);
+ flush_patch_area(text_poke_addr);
return err;
}
@@ -488,7 +505,7 @@ static int __do_patch_instructions(u32 *addr, u32 *code, size_t len, bool repeat
err = __patch_instructions(patch_addr, code, len, repeat_instr);
pte_clear(&init_mm, text_poke_addr, pte);
- flush_tlb_kernel_range(text_poke_addr, text_poke_addr + PAGE_SIZE);
+ flush_patch_area(text_poke_addr);
return err;
}
--
2.39.5
next reply other threads:[~2026-11-03 2:54 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 2:54 Ritesh Harjani (IBM) [this message]
2026-11-03 7:33 ` Christophe Leroy (CS GROUP)
2026-11-03 9:12 ` Ritesh Harjani
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b7916dadd8ef56d417d0cbf69fa9ef2a447a5a3e.1793674111.git.ritesh.list@gmail.com \
--to=ritesh.list@gmail.com \
--cc=chleroy@kernel.org \
--cc=hbathini@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
--cc=pepe.schlehofer@gmail.com \
--cc=stable@vger.kernel.org \
--cc=venkat88@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®