The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: bpf@vger.kernel.org, jolsa@kernel.org
Cc: Jiayuan Chen <jiayuan.chen@linux.dev>,
	Andrii Nakryiko <andrii@kernel.org>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Ihor Solodrai <ihor.solodrai@linux.dev>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Song Liu <song@kernel.org>,
	Yonghong Song <yonghong.song@linux.dev>,
	Emil Tsalapatis <emil@etsalapatis.com>,
	Shuah Khan <shuah@kernel.org>,
	Jakub Sitnicki <jakub@cloudflare.com>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Jiawei Zhao <phoenix500526@163.com>,
	Ingo Molnar <mingo@kernel.org>,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [PATCH bpf v2 2/2] selftests/bpf: Add test for usdt probe with page-crossing nop10
Date: Tue, 25 Aug 2026 23:04:34 +0800	[thread overview]
Message-ID: <20260825150444.31603-2-jiayuan.chen@linux.dev> (raw)
In-Reply-To: <20260825150444.31603-1-jiayuan.chen@linux.dev>

Add a USDT probe laid out so that its nop10 crosses a page boundary
and check that attaching to it succeeds and the probe fires. Without
the previous fix libbpf shifts the uprobe onto the nop10 and the
attach fails with -ENOTSUPP.

Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
 tools/testing/selftests/bpf/prog_tests/usdt.c | 54 +++++++++++++++++++
 tools/testing/selftests/bpf/usdt_2.c          | 16 ++++++
 2 files changed, 70 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/usdt.c b/tools/testing/selftests/bpf/prog_tests/usdt.c
index 8004c9568ffa..eff1e57ab13c 100644
--- a/tools/testing/selftests/bpf/prog_tests/usdt.c
+++ b/tools/testing/selftests/bpf/prog_tests/usdt.c
@@ -250,6 +250,7 @@ static void subtest_basic_usdt(bool optimized)
 #ifdef __x86_64__
 extern void usdt_1(void);
 extern void usdt_2(void);
+extern void usdt_2_cross_page(void);
 extern void usdt_red_zone_trigger(void);
 
 static unsigned char nop1[1] = { 0x90 };
@@ -342,6 +343,57 @@ static void subtest_optimized_attach(void)
 	test_usdt__destroy(skel);
 }
 
+/*
+ * Test attachment to a USDT probe whose nop10 crosses a page boundary.
+ * The kernel can't optimize such nop10, so libbpf keeps the uprobe on
+ * the preceding 1-byte nop. Do not assume any particular placement
+ * here, though: however the probe ends up attached, the attachment
+ * must succeed and the probe must fire.
+ */
+static void subtest_optimized_attach_cross_page(void)
+{
+	long page_sz = sysconf(_SC_PAGESIZE);
+	struct test_usdt *skel;
+	__u8 *addr = NULL;
+	long i;
+
+	/* combo is placed up to a page of padding after the function start */
+	for (i = 0; i < 2 * page_sz; i++) {
+		if (!memcmp((void *)usdt_2_cross_page + i, nop1_nop10_combo, 11)) {
+			addr = (void *)usdt_2_cross_page + i;
+			break;
+		}
+	}
+	if (!ASSERT_OK_PTR(addr, "find_nop1_nop10_combo"))
+		return;
+
+	/* layout sanity check: the nop10 must cross the page boundary */
+	if (!ASSERT_GT((unsigned long)(addr + 1) % page_sz + 10, page_sz,
+		       "nop10_crosses_page"))
+		return;
+
+	skel = test_usdt__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "test_usdt__open_and_load"))
+		return;
+
+	skel->bss->my_pid = getpid();
+
+	skel->links.usdt0 = bpf_program__attach_usdt(skel->progs.usdt0,
+						     0 /*self*/, "/proc/self/exe",
+						     "optimized_attach",
+						     "usdt_2_cross_page", NULL);
+	if (!ASSERT_OK_PTR(skel->links.usdt0, "bpf_program__attach_usdt"))
+		goto cleanup;
+
+	usdt_2_cross_page();
+	usdt_2_cross_page();
+
+	ASSERT_EQ(skel->bss->usdt0_called, 2, "usdt0_called");
+
+cleanup:
+	test_usdt__destroy(skel);
+}
+
 /*
  * Test that USDT arguments survive nop10 optimization in a function where
  * the compiler places operands in the red zone.
@@ -660,6 +712,8 @@ void test_usdt(void)
 		subtest_basic_usdt(true);
 	if (test__start_subtest("optimized_attach"))
 		subtest_optimized_attach();
+	if (test__start_subtest("optimized_attach_cross_page"))
+		subtest_optimized_attach_cross_page();
 	if (test__start_subtest("optimized_red_zone"))
 		subtest_optimized_red_zone();
 #endif
diff --git a/tools/testing/selftests/bpf/usdt_2.c b/tools/testing/selftests/bpf/usdt_2.c
index 5e38f8605b02..3b7024b9b08b 100644
--- a/tools/testing/selftests/bpf/usdt_2.c
+++ b/tools/testing/selftests/bpf/usdt_2.c
@@ -13,6 +13,22 @@ void usdt_2(void)
 	USDT(optimized_attach, usdt_2);
 }
 
+/*
+ * Force the nop1,nop10 combo of the USDT probe to a spot where the nop10
+ * crosses a page boundary: .balign starts the padding exactly at a page
+ * start regardless of the compiler-generated prologue size, and the 4086
+ * one-byte nops put the nop1 at page offset 4086, so the following nop10
+ * occupies the last 9 bytes of that page and 1 byte of the next one.
+ * The kernel can't optimize such nop10, so libbpf must keep the uprobe
+ * on the 1-byte nop.
+ */
+__attribute__((noinline))
+void usdt_2_cross_page(void)
+{
+	asm volatile (".balign 4096, 0x90\n\t.skip 4086, 0x90");
+	USDT(optimized_attach, usdt_2_cross_page);
+}
+
 static volatile unsigned long usdt_red_zone_arg1 = 0xDEADBEEF;
 static volatile unsigned long usdt_red_zone_arg2 = 0xCAFEBABE;
 static volatile unsigned long usdt_red_zone_arg3 = 0xFEEDFACE;
-- 
2.43.0


  reply	other threads:[~2026-08-25 15:05 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-25 15:04 [PATCH bpf v2 1/2] libbpf: Fix usdt attach failure when nop10 crosses page boundary Jiayuan Chen
2026-08-25 15:04 ` Jiayuan Chen [this message]
2026-08-25 18:39 ` Andrii Nakryiko
2026-08-25 22:08 ` patchwork-bot+netdevbpf

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=20260825150444.31603-2-jiayuan.chen@linux.dev \
    --to=jiayuan.chen@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=jakub@cloudflare.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=phoenix500526@163.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=yonghong.song@linux.dev \
    /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