From: Andi Kleen <ak@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: mhiramat@kernel.org, oleg@redhat.com, peterz@infradead.org,
tglx@kernel.org, x86@kernel.org, jolsa@kernel.org,
linux-perf-users@vger.kernel.org, adrian.hunter@intel.com,
Andi Kleen <ak@kernel.org>
Subject: [RFC v1 14/19] ptwrite uprobes: Use atomic patching for multinop sites
Date: Mon, 31 Aug 2026 08:04:50 -0700 [thread overview]
Message-ID: <20260831150651.1134594-15-ak@kernel.org> (raw)
In-Reply-To: <20260831150651.1134594-1-ak@kernel.org>
The earlier multinop patching is not quite safe because the cross
modified CPU could be already executing on a later nop when the
cross patching occurs. The Intel SDM allows cross modification
by larger stores as long as they are aligned. AMD has a similar
guarantee.
The motivation for multinop is mainly to support the gcc
function entry patch sites and these are always aligned.
So enforce 8 bytes alignment of the multinop and use a safe RMW 8 byte store
ot overwrite the 5 byte sequence. This assumes that the code is not
changing in parallel, but if that happens cross modification safety
is probably the smallest of the issues.
Assisted-by: omp:gpt-5.6-luna sashiko
Signed-off-by: Andi Kleen <ak@kernel.org>
---
arch/x86/kernel/uprobes.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 806e40f7b0ab..8d9dadc2b1fc 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -1812,8 +1812,9 @@ get_uprobe_ptwrite_page(struct mm_struct *mm, unsigned long vaddr,
}
/*
- * A run of short NOPs is accepted only when requested. This validation does
- * not make the three-phase poke safe for threads that already passed byte 0.
+ * A run of short NOPs is accepted only when requested. It is patched with
+ * an aligned eight-byte read-modify-write, preserving the following bytes;
+ * code is not expected to change concurrently.
*/
static bool pun_site_is_nop(const u8 *orig, bool allow_nop_run)
{
@@ -1831,6 +1832,13 @@ static bool pun_site_is_nop(const u8 *orig, bool allow_nop_run)
orig[2] == 0x90 && orig[3] == 0x90 && orig[4] == 0x90;
}
+/* Identify the explicitly opted-in run of five one-byte NOPs. */
+static bool ptwrite_site_is_multinop(const u8 *orig, bool allow_nop_run)
+{
+ return allow_nop_run && orig[0] == 0x90 && orig[1] == 0x90 &&
+ orig[2] == 0x90 && orig[3] == 0x90 && orig[4] == 0x90;
+}
+
/*
* Classify the site's single instruction for out-of-line execution.
* Returns the length, or 0 when it cannot run safely out of line.
@@ -2224,6 +2232,9 @@ int arch_uprobe_install_ptwrite(struct arch_uprobe *auprobe,
ret = copy_from_vaddr(mm, vaddr, orig, sizeof(orig));
if (ret)
return ret;
+ if (ptwrite_site_is_multinop(orig, ptw_a->allow_nop_run) &&
+ (vaddr & 7))
+ return pun_install(auprobe, vma, vaddr, orig);
if (ptwrite_is_installed(mm, vaddr, orig))
return 0;
@@ -2249,9 +2260,13 @@ int arch_uprobe_install_ptwrite(struct arch_uprobe *auprobe,
continue;
if (!__in_uprobe_ptwrite(mm, ptw->vaddr))
continue;
- ret = ptwrite_text_poke(auprobe, vma, vaddr,
- ptw->vaddr + ptw->index[b].off);
- goto out;
+ if (ptwrite_site_is_multinop(orig, ptw_a->allow_nop_run))
+ ret = ptwrite_multinop_text_poke(auprobe, vma, vaddr,
+ ptw->vaddr + ptw->index[b].off);
+ else
+ ret = ptwrite_text_poke(auprobe, vma, vaddr,
+ ptw->vaddr + ptw->index[b].off);
+ return ret;
}
ptw = get_uprobe_ptwrite_page(mm, vaddr, ptw_a->stub_len);
if (!ptw)
@@ -2287,8 +2302,11 @@ int arch_uprobe_install_ptwrite(struct arch_uprobe *auprobe,
memcpy(kaddr + block_off + ptw_a->jmp_off, &rel, sizeof(rel));
kunmap_local(kaddr);
- ret = ptwrite_text_poke(auprobe, vma, vaddr, stub_addr);
- if (ret)
+ if (ptwrite_site_is_multinop(orig, ptw_a->allow_nop_run))
+ ret = ptwrite_multinop_text_poke(auprobe, vma, vaddr, stub_addr);
+ else
+ ret = ptwrite_text_poke(auprobe, vma, vaddr, stub_addr);
+ if (ret) {
/* Publish rollback before readers use the reduced block count. */
smp_store_release(&ptw->nblocks, ptw->nblocks - 1);
return ret;
--
2.54.0
next prev parent reply other threads:[~2026-08-31 15:07 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 15:04 [RFC] ptwrite uprobes Andi Kleen
2026-08-31 15:04 ` [RFC v1 01/19] uprobes: guard trace cleanup against error pointers Andi Kleen
2026-08-31 18:15 ` sashiko-bot
2026-09-01 0:49 ` Masami Hiramatsu
2026-08-31 15:04 ` [RFC v1 02/19] uprobes: Correctly reject anonymous VMAs for breakpoint installation Andi Kleen
2026-08-31 18:29 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 03/19] uprobes: Print warning for missing breakpoint install Andi Kleen
2026-08-31 18:42 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 04/19] ptwrite uprobes: Add infrastructure for ptwrite uprobes Andi Kleen
2026-08-31 18:55 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 05/19] ptwrite uprobes: Add minimal low level support for x86 Andi Kleen
2026-08-31 19:11 ` sashiko-bot
2026-09-02 16:35 ` Lorenzo Stoakes (ARM)
2026-08-31 15:04 ` [RFC v1 06/19] ptwrite uprobes: Add a sample module to exercise interface Andi Kleen
2026-08-31 19:19 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 07/19] ptwrite uprobes: Add support to tracing infrastructure Andi Kleen
2026-08-31 19:31 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 08/19] ptwrite uprobes / x86: Add a user fault notifier chain Andi Kleen
2026-08-31 19:38 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 09/19] ptwrite uprobes: Factor file-backed instruction reads Andi Kleen
2026-08-31 19:45 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 10/19] ptwrite uprobes: Minimal memory references and fault handling Andi Kleen
2026-08-31 19:59 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 11/19] ptwrite uprobes: Add multinop support Andi Kleen
2026-08-31 20:09 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 12/19] ptwrite uprobes: Add pacing to the probes Andi Kleen
2026-08-31 20:19 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 13/19] ptwrite uprobes: Support instruction puning Andi Kleen
2026-08-31 20:39 ` sashiko-bot
2026-08-31 15:04 ` Andi Kleen [this message]
2026-08-31 21:08 ` [RFC v1 14/19] ptwrite uprobes: Use atomic patching for multinop sites sashiko-bot
2026-08-31 15:04 ` [RFC v1 15/19] ptwrite uprobes: Add a tutorial and overview documentation Andi Kleen
2026-08-31 21:10 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 16/19] ptwrite uprobes / perf tools pt: Improve FUP error handling for ptwrite Andi Kleen
2026-08-31 21:19 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 17/19] ptwrite uprobes / perf tools probe: Add support of ptwrite probes Andi Kleen
2026-08-31 21:32 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 18/19] ptwrite uprobes / perf tools script: Add ptwrite uprobes decoder Andi Kleen
2026-08-31 21:39 ` sashiko-bot
2026-08-31 15:04 ` [RFC v1 19/19] ptwrite uprobes: Add self tests Andi Kleen
2026-08-31 21:47 ` sashiko-bot
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=20260831150651.1134594-15-ak@kernel.org \
--to=ak@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@kernel.org \
--cc=x86@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.