Skip to content

Commit fc443b7

Browse files
Phoenix500526Kernel Patches Daemon
authored andcommitted
selftests/bpf: Enrich subtest_basic_usdt case in selftests to cover SIB handling logic
When using GCC on x86-64 to compile an usdt prog with -O1 or higher optimization, the compiler will generate SIB addressing mode for global array and PC-relative addressing mode for global variable, e.g. "1@-96(%rbp,%rax,8)" and "-1@4+t1(%rip)". In this patch: - enrich subtest_basic_usdt test case to cover SIB addressing usdt argument spec handling logic Signed-off-by: Jiawei Zhao <[email protected]>
1 parent a73c021 commit fc443b7

File tree

2 files changed

+72
-2
lines changed

2 files changed

+72
-2
lines changed

tools/testing/selftests/bpf/prog_tests/usdt.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ unsigned short test_usdt0_semaphore SEC(".probes");
2525
unsigned short test_usdt3_semaphore SEC(".probes");
2626
unsigned short test_usdt12_semaphore SEC(".probes");
2727

28+
#if ((defined(__x86_64__) || defined(__i386__)) && defined(__GNUC__) && !defined(__clang__))
29+
unsigned short test_usdt_sib_semaphore SEC(".probes");
30+
#endif
31+
2832
static void __always_inline trigger_func(int x) {
2933
long y = 42;
3034

@@ -40,12 +44,29 @@ static void __always_inline trigger_func(int x) {
4044
}
4145
}
4246

47+
#if ((defined(__x86_64__) || defined(__i386__)) && defined(__GNUC__) && !defined(__clang__))
48+
static __attribute__((optimize("O1"))) void trigger_sib_spec(void)
49+
{
50+
/* Base address + offset + (index * scale) */
51+
/* Force SIB addressing with inline assembly */
52+
asm volatile(
53+
"# probe point with memory access\n"
54+
STAP_PROBE_ASM(test, usdt_sib, -2@(%%rdx,%%rax,2))
55+
"# end probe point"
56+
:
57+
: "d"(nums), "a"(0)
58+
: "memory"
59+
);
60+
}
61+
#endif
62+
4363
static void subtest_basic_usdt(void)
4464
{
4565
LIBBPF_OPTS(bpf_usdt_opts, opts);
4666
struct test_usdt *skel;
4767
struct test_usdt__bss *bss;
4868
int err, i;
69+
const __u64 expected_cookie = 0xcafedeadbeeffeed;
4970

5071
skel = test_usdt__open_and_load();
5172
if (!ASSERT_OK_PTR(skel, "skel_open"))
@@ -59,20 +80,29 @@ static void subtest_basic_usdt(void)
5980
goto cleanup;
6081

6182
/* usdt0 won't be auto-attached */
62-
opts.usdt_cookie = 0xcafedeadbeeffeed;
83+
opts.usdt_cookie = expected_cookie;
6384
skel->links.usdt0 = bpf_program__attach_usdt(skel->progs.usdt0,
6485
0 /*self*/, "/proc/self/exe",
6586
"test", "usdt0", &opts);
6687
if (!ASSERT_OK_PTR(skel->links.usdt0, "usdt0_link"))
6788
goto cleanup;
6889

90+
#if ((defined(__x86_64__) || defined(__i386__)) && defined(__GNUC__) && !defined(__clang__))
91+
opts.usdt_cookie = expected_cookie;
92+
skel->links.usdt_sib = bpf_program__attach_usdt(skel->progs.usdt_sib,
93+
0 /*self*/, "/proc/self/exe",
94+
"test", "usdt_sib", &opts);
95+
if (!ASSERT_OK_PTR(skel->links.usdt_sib, "usdt_sib_link"))
96+
goto cleanup;
97+
#endif
98+
6999
trigger_func(1);
70100

71101
ASSERT_EQ(bss->usdt0_called, 1, "usdt0_called");
72102
ASSERT_EQ(bss->usdt3_called, 1, "usdt3_called");
73103
ASSERT_EQ(bss->usdt12_called, 1, "usdt12_called");
74104

75-
ASSERT_EQ(bss->usdt0_cookie, 0xcafedeadbeeffeed, "usdt0_cookie");
105+
ASSERT_EQ(bss->usdt0_cookie, expected_cookie, "usdt0_cookie");
76106
ASSERT_EQ(bss->usdt0_arg_cnt, 0, "usdt0_arg_cnt");
77107
ASSERT_EQ(bss->usdt0_arg_ret, -ENOENT, "usdt0_arg_ret");
78108
ASSERT_EQ(bss->usdt0_arg_size, -ENOENT, "usdt0_arg_size");
@@ -156,6 +186,16 @@ static void subtest_basic_usdt(void)
156186
ASSERT_EQ(bss->usdt3_args[1], 42, "usdt3_arg2");
157187
ASSERT_EQ(bss->usdt3_args[2], (uintptr_t)&bla, "usdt3_arg3");
158188

189+
#if ((defined(__x86_64__) || defined(__i386__)) && defined(__GNUC__) && !defined(__clang__))
190+
trigger_sib_spec();
191+
ASSERT_EQ(bss->usdt_sib_called, 1, "usdt_sib_called");
192+
ASSERT_EQ(bss->usdt_sib_cookie, expected_cookie, "usdt_sib_cookie");
193+
ASSERT_EQ(bss->usdt_sib_arg_cnt, 1, "usdt_sib_arg_cnt");
194+
ASSERT_EQ(bss->usdt_sib_arg, nums[0], "usdt_sib_arg");
195+
ASSERT_EQ(bss->usdt_sib_arg_ret, 0, "usdt_sib_arg_ret");
196+
ASSERT_EQ(bss->usdt_sib_arg_size, sizeof(nums[0]), "usdt_sib_arg_size");
197+
#endif
198+
159199
cleanup:
160200
test_usdt__destroy(skel);
161201
}

tools/testing/selftests/bpf/progs/test_usdt.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,34 @@ int BPF_USDT(usdt12, int a1, int a2, long a3, long a4, unsigned a5,
107107
return 0;
108108
}
109109

110+
111+
int usdt_sib_called;
112+
u64 usdt_sib_cookie;
113+
int usdt_sib_arg_cnt;
114+
int usdt_sib_arg_ret;
115+
u64 usdt_sib_arg;
116+
int usdt_sib_arg_size;
117+
118+
// Note: usdt_sib is only tested on x86-related architectures, so it requires
119+
// manual attach since auto-attach will panic tests under other architectures
120+
SEC("usdt")
121+
int usdt_sib(struct pt_regs *ctx)
122+
{
123+
long tmp;
124+
125+
if (my_pid != (bpf_get_current_pid_tgid() >> 32))
126+
return 0;
127+
128+
__sync_fetch_and_add(&usdt_sib_called, 1);
129+
130+
usdt_sib_cookie = bpf_usdt_cookie(ctx);
131+
usdt_sib_arg_cnt = bpf_usdt_arg_cnt(ctx);
132+
133+
usdt_sib_arg_ret = bpf_usdt_arg(ctx, 0, &tmp);
134+
usdt_sib_arg = (short)tmp;
135+
usdt_sib_arg_size = bpf_usdt_arg_size(ctx, 0);
136+
137+
return 0;
138+
}
139+
110140
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)