1b9e94a7bSTiezhu Yang // SPDX-License-Identifier: GPL-2.0-or-later
2b9e94a7bSTiezhu Yang /*
3b9e94a7bSTiezhu Yang * test_kprobes.c - simple sanity test for *probes
4b9e94a7bSTiezhu Yang *
5b9e94a7bSTiezhu Yang * Copyright IBM Corp. 2008
6b9e94a7bSTiezhu Yang */
7b9e94a7bSTiezhu Yang
8b9e94a7bSTiezhu Yang #include <linux/kernel.h>
9b9e94a7bSTiezhu Yang #include <linux/kprobes.h>
10b9e94a7bSTiezhu Yang #include <linux/random.h>
11b9e94a7bSTiezhu Yang #include <kunit/test.h>
12b9e94a7bSTiezhu Yang
13b9e94a7bSTiezhu Yang #define div_factor 3
14b9e94a7bSTiezhu Yang
15b9e94a7bSTiezhu Yang static u32 rand1, preh_val, posth_val;
16b9e94a7bSTiezhu Yang static u32 (*target)(u32 value);
17*1fcd09fdSMasami Hiramatsu (Google) static u32 (*recursed_target)(u32 value);
18b9e94a7bSTiezhu Yang static u32 (*target2)(u32 value);
19b9e94a7bSTiezhu Yang static struct kunit *current_test;
20b9e94a7bSTiezhu Yang
21b9e94a7bSTiezhu Yang static unsigned long (*internal_target)(void);
22b9e94a7bSTiezhu Yang static unsigned long (*stacktrace_target)(void);
23b9e94a7bSTiezhu Yang static unsigned long (*stacktrace_driver)(void);
24b9e94a7bSTiezhu Yang static unsigned long target_return_address[2];
25b9e94a7bSTiezhu Yang
kprobe_target(u32 value)26b9e94a7bSTiezhu Yang static noinline u32 kprobe_target(u32 value)
27b9e94a7bSTiezhu Yang {
28b9e94a7bSTiezhu Yang return (value / div_factor);
29b9e94a7bSTiezhu Yang }
30b9e94a7bSTiezhu Yang
kprobe_recursed_target(u32 value)31*1fcd09fdSMasami Hiramatsu (Google) static noinline u32 kprobe_recursed_target(u32 value)
32*1fcd09fdSMasami Hiramatsu (Google) {
33*1fcd09fdSMasami Hiramatsu (Google) return (value / div_factor);
34*1fcd09fdSMasami Hiramatsu (Google) }
35*1fcd09fdSMasami Hiramatsu (Google)
kp_pre_handler(struct kprobe * p,struct pt_regs * regs)36b9e94a7bSTiezhu Yang static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
37b9e94a7bSTiezhu Yang {
38b9e94a7bSTiezhu Yang KUNIT_EXPECT_FALSE(current_test, preemptible());
39*1fcd09fdSMasami Hiramatsu (Google)
40*1fcd09fdSMasami Hiramatsu (Google) preh_val = recursed_target(rand1);
41b9e94a7bSTiezhu Yang return 0;
42b9e94a7bSTiezhu Yang }
43b9e94a7bSTiezhu Yang
kp_post_handler(struct kprobe * p,struct pt_regs * regs,unsigned long flags)44b9e94a7bSTiezhu Yang static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
45b9e94a7bSTiezhu Yang unsigned long flags)
46b9e94a7bSTiezhu Yang {
47*1fcd09fdSMasami Hiramatsu (Google) u32 expval = recursed_target(rand1);
48*1fcd09fdSMasami Hiramatsu (Google)
49b9e94a7bSTiezhu Yang KUNIT_EXPECT_FALSE(current_test, preemptible());
50*1fcd09fdSMasami Hiramatsu (Google) KUNIT_EXPECT_EQ(current_test, preh_val, expval);
51*1fcd09fdSMasami Hiramatsu (Google)
52b9e94a7bSTiezhu Yang posth_val = preh_val + div_factor;
53b9e94a7bSTiezhu Yang }
54b9e94a7bSTiezhu Yang
55b9e94a7bSTiezhu Yang static struct kprobe kp = {
56b9e94a7bSTiezhu Yang .symbol_name = "kprobe_target",
57b9e94a7bSTiezhu Yang .pre_handler = kp_pre_handler,
58b9e94a7bSTiezhu Yang .post_handler = kp_post_handler
59b9e94a7bSTiezhu Yang };
60b9e94a7bSTiezhu Yang
test_kprobe(struct kunit * test)61b9e94a7bSTiezhu Yang static void test_kprobe(struct kunit *test)
62b9e94a7bSTiezhu Yang {
63b9e94a7bSTiezhu Yang current_test = test;
64b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp));
65b9e94a7bSTiezhu Yang target(rand1);
66b9e94a7bSTiezhu Yang unregister_kprobe(&kp);
67b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(test, 0, preh_val);
68b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(test, 0, posth_val);
69b9e94a7bSTiezhu Yang }
70b9e94a7bSTiezhu Yang
kprobe_target2(u32 value)71b9e94a7bSTiezhu Yang static noinline u32 kprobe_target2(u32 value)
72b9e94a7bSTiezhu Yang {
73b9e94a7bSTiezhu Yang return (value / div_factor) + 1;
74b9e94a7bSTiezhu Yang }
75b9e94a7bSTiezhu Yang
kprobe_stacktrace_internal_target(void)76b9e94a7bSTiezhu Yang static noinline unsigned long kprobe_stacktrace_internal_target(void)
77b9e94a7bSTiezhu Yang {
78b9e94a7bSTiezhu Yang if (!target_return_address[0])
79b9e94a7bSTiezhu Yang target_return_address[0] = (unsigned long)__builtin_return_address(0);
80b9e94a7bSTiezhu Yang return target_return_address[0];
81b9e94a7bSTiezhu Yang }
82b9e94a7bSTiezhu Yang
kprobe_stacktrace_target(void)83b9e94a7bSTiezhu Yang static noinline unsigned long kprobe_stacktrace_target(void)
84b9e94a7bSTiezhu Yang {
85b9e94a7bSTiezhu Yang if (!target_return_address[1])
86b9e94a7bSTiezhu Yang target_return_address[1] = (unsigned long)__builtin_return_address(0);
87b9e94a7bSTiezhu Yang
88b9e94a7bSTiezhu Yang if (internal_target)
89b9e94a7bSTiezhu Yang internal_target();
90b9e94a7bSTiezhu Yang
91b9e94a7bSTiezhu Yang return target_return_address[1];
92b9e94a7bSTiezhu Yang }
93b9e94a7bSTiezhu Yang
kprobe_stacktrace_driver(void)94b9e94a7bSTiezhu Yang static noinline unsigned long kprobe_stacktrace_driver(void)
95b9e94a7bSTiezhu Yang {
96b9e94a7bSTiezhu Yang if (stacktrace_target)
97b9e94a7bSTiezhu Yang stacktrace_target();
98b9e94a7bSTiezhu Yang
99b9e94a7bSTiezhu Yang /* This is for preventing inlining the function */
100b9e94a7bSTiezhu Yang return (unsigned long)__builtin_return_address(0);
101b9e94a7bSTiezhu Yang }
102b9e94a7bSTiezhu Yang
kp_pre_handler2(struct kprobe * p,struct pt_regs * regs)103b9e94a7bSTiezhu Yang static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
104b9e94a7bSTiezhu Yang {
105b9e94a7bSTiezhu Yang preh_val = (rand1 / div_factor) + 1;
106b9e94a7bSTiezhu Yang return 0;
107b9e94a7bSTiezhu Yang }
108b9e94a7bSTiezhu Yang
kp_post_handler2(struct kprobe * p,struct pt_regs * regs,unsigned long flags)109b9e94a7bSTiezhu Yang static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
110b9e94a7bSTiezhu Yang unsigned long flags)
111b9e94a7bSTiezhu Yang {
112b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor) + 1);
113b9e94a7bSTiezhu Yang posth_val = preh_val + div_factor;
114b9e94a7bSTiezhu Yang }
115b9e94a7bSTiezhu Yang
116b9e94a7bSTiezhu Yang static struct kprobe kp2 = {
117b9e94a7bSTiezhu Yang .symbol_name = "kprobe_target2",
118b9e94a7bSTiezhu Yang .pre_handler = kp_pre_handler2,
119b9e94a7bSTiezhu Yang .post_handler = kp_post_handler2
120b9e94a7bSTiezhu Yang };
121b9e94a7bSTiezhu Yang
test_kprobes(struct kunit * test)122b9e94a7bSTiezhu Yang static void test_kprobes(struct kunit *test)
123b9e94a7bSTiezhu Yang {
124b9e94a7bSTiezhu Yang struct kprobe *kps[2] = {&kp, &kp2};
125b9e94a7bSTiezhu Yang
126b9e94a7bSTiezhu Yang current_test = test;
127b9e94a7bSTiezhu Yang
128b9e94a7bSTiezhu Yang /* addr and flags should be cleard for reusing kprobe. */
129b9e94a7bSTiezhu Yang kp.addr = NULL;
130b9e94a7bSTiezhu Yang kp.flags = 0;
131b9e94a7bSTiezhu Yang
132b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(test, 0, register_kprobes(kps, 2));
133b9e94a7bSTiezhu Yang preh_val = 0;
134b9e94a7bSTiezhu Yang posth_val = 0;
135b9e94a7bSTiezhu Yang target(rand1);
136b9e94a7bSTiezhu Yang
137b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(test, 0, preh_val);
138b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(test, 0, posth_val);
139b9e94a7bSTiezhu Yang
140b9e94a7bSTiezhu Yang preh_val = 0;
141b9e94a7bSTiezhu Yang posth_val = 0;
142b9e94a7bSTiezhu Yang target2(rand1);
143b9e94a7bSTiezhu Yang
144b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(test, 0, preh_val);
145b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(test, 0, posth_val);
146b9e94a7bSTiezhu Yang unregister_kprobes(kps, 2);
147b9e94a7bSTiezhu Yang }
148b9e94a7bSTiezhu Yang
149*1fcd09fdSMasami Hiramatsu (Google) static struct kprobe kp_missed = {
150*1fcd09fdSMasami Hiramatsu (Google) .symbol_name = "kprobe_recursed_target",
151*1fcd09fdSMasami Hiramatsu (Google) .pre_handler = kp_pre_handler,
152*1fcd09fdSMasami Hiramatsu (Google) .post_handler = kp_post_handler,
153*1fcd09fdSMasami Hiramatsu (Google) };
154*1fcd09fdSMasami Hiramatsu (Google)
test_kprobe_missed(struct kunit * test)155*1fcd09fdSMasami Hiramatsu (Google) static void test_kprobe_missed(struct kunit *test)
156*1fcd09fdSMasami Hiramatsu (Google) {
157*1fcd09fdSMasami Hiramatsu (Google) current_test = test;
158*1fcd09fdSMasami Hiramatsu (Google) preh_val = 0;
159*1fcd09fdSMasami Hiramatsu (Google) posth_val = 0;
160*1fcd09fdSMasami Hiramatsu (Google)
161*1fcd09fdSMasami Hiramatsu (Google) KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp_missed));
162*1fcd09fdSMasami Hiramatsu (Google)
163*1fcd09fdSMasami Hiramatsu (Google) recursed_target(rand1);
164*1fcd09fdSMasami Hiramatsu (Google)
165*1fcd09fdSMasami Hiramatsu (Google) KUNIT_EXPECT_EQ(test, 2, kp_missed.nmissed);
166*1fcd09fdSMasami Hiramatsu (Google) KUNIT_EXPECT_NE(test, 0, preh_val);
167*1fcd09fdSMasami Hiramatsu (Google) KUNIT_EXPECT_NE(test, 0, posth_val);
168*1fcd09fdSMasami Hiramatsu (Google)
169*1fcd09fdSMasami Hiramatsu (Google) unregister_kprobe(&kp_missed);
170*1fcd09fdSMasami Hiramatsu (Google) }
171*1fcd09fdSMasami Hiramatsu (Google)
172b9e94a7bSTiezhu Yang #ifdef CONFIG_KRETPROBES
173b9e94a7bSTiezhu Yang static u32 krph_val;
174b9e94a7bSTiezhu Yang
entry_handler(struct kretprobe_instance * ri,struct pt_regs * regs)175b9e94a7bSTiezhu Yang static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
176b9e94a7bSTiezhu Yang {
177b9e94a7bSTiezhu Yang KUNIT_EXPECT_FALSE(current_test, preemptible());
178b9e94a7bSTiezhu Yang krph_val = (rand1 / div_factor);
179b9e94a7bSTiezhu Yang return 0;
180b9e94a7bSTiezhu Yang }
181b9e94a7bSTiezhu Yang
return_handler(struct kretprobe_instance * ri,struct pt_regs * regs)182b9e94a7bSTiezhu Yang static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
183b9e94a7bSTiezhu Yang {
184b9e94a7bSTiezhu Yang unsigned long ret = regs_return_value(regs);
185b9e94a7bSTiezhu Yang
186b9e94a7bSTiezhu Yang KUNIT_EXPECT_FALSE(current_test, preemptible());
187b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, ret, rand1 / div_factor);
188b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(current_test, krph_val, 0);
189b9e94a7bSTiezhu Yang krph_val = rand1;
190b9e94a7bSTiezhu Yang return 0;
191b9e94a7bSTiezhu Yang }
192b9e94a7bSTiezhu Yang
193b9e94a7bSTiezhu Yang static struct kretprobe rp = {
194b9e94a7bSTiezhu Yang .handler = return_handler,
195b9e94a7bSTiezhu Yang .entry_handler = entry_handler,
196b9e94a7bSTiezhu Yang .kp.symbol_name = "kprobe_target"
197b9e94a7bSTiezhu Yang };
198b9e94a7bSTiezhu Yang
test_kretprobe(struct kunit * test)199b9e94a7bSTiezhu Yang static void test_kretprobe(struct kunit *test)
200b9e94a7bSTiezhu Yang {
201b9e94a7bSTiezhu Yang current_test = test;
202b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(test, 0, register_kretprobe(&rp));
203b9e94a7bSTiezhu Yang target(rand1);
204b9e94a7bSTiezhu Yang unregister_kretprobe(&rp);
205b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(test, krph_val, rand1);
206b9e94a7bSTiezhu Yang }
207b9e94a7bSTiezhu Yang
return_handler2(struct kretprobe_instance * ri,struct pt_regs * regs)208b9e94a7bSTiezhu Yang static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
209b9e94a7bSTiezhu Yang {
210b9e94a7bSTiezhu Yang unsigned long ret = regs_return_value(regs);
211b9e94a7bSTiezhu Yang
212b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
213b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(current_test, krph_val, 0);
214b9e94a7bSTiezhu Yang krph_val = rand1;
215b9e94a7bSTiezhu Yang return 0;
216b9e94a7bSTiezhu Yang }
217b9e94a7bSTiezhu Yang
218b9e94a7bSTiezhu Yang static struct kretprobe rp2 = {
219b9e94a7bSTiezhu Yang .handler = return_handler2,
220b9e94a7bSTiezhu Yang .entry_handler = entry_handler,
221b9e94a7bSTiezhu Yang .kp.symbol_name = "kprobe_target2"
222b9e94a7bSTiezhu Yang };
223b9e94a7bSTiezhu Yang
test_kretprobes(struct kunit * test)224b9e94a7bSTiezhu Yang static void test_kretprobes(struct kunit *test)
225b9e94a7bSTiezhu Yang {
226b9e94a7bSTiezhu Yang struct kretprobe *rps[2] = {&rp, &rp2};
227b9e94a7bSTiezhu Yang
228b9e94a7bSTiezhu Yang current_test = test;
229b9e94a7bSTiezhu Yang /* addr and flags should be cleard for reusing kprobe. */
230b9e94a7bSTiezhu Yang rp.kp.addr = NULL;
231b9e94a7bSTiezhu Yang rp.kp.flags = 0;
232b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(test, 0, register_kretprobes(rps, 2));
233b9e94a7bSTiezhu Yang
234b9e94a7bSTiezhu Yang krph_val = 0;
235b9e94a7bSTiezhu Yang target(rand1);
236b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(test, krph_val, rand1);
237b9e94a7bSTiezhu Yang
238b9e94a7bSTiezhu Yang krph_val = 0;
239b9e94a7bSTiezhu Yang target2(rand1);
240b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(test, krph_val, rand1);
241b9e94a7bSTiezhu Yang unregister_kretprobes(rps, 2);
242b9e94a7bSTiezhu Yang }
243b9e94a7bSTiezhu Yang
244b9e94a7bSTiezhu Yang #ifdef CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
245b9e94a7bSTiezhu Yang #define STACK_BUF_SIZE 16
246b9e94a7bSTiezhu Yang static unsigned long stack_buf[STACK_BUF_SIZE];
247b9e94a7bSTiezhu Yang
stacktrace_return_handler(struct kretprobe_instance * ri,struct pt_regs * regs)248b9e94a7bSTiezhu Yang static int stacktrace_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
249b9e94a7bSTiezhu Yang {
250b9e94a7bSTiezhu Yang unsigned long retval = regs_return_value(regs);
251b9e94a7bSTiezhu Yang int i, ret;
252b9e94a7bSTiezhu Yang
253b9e94a7bSTiezhu Yang KUNIT_EXPECT_FALSE(current_test, preemptible());
254b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, retval, target_return_address[1]);
255b9e94a7bSTiezhu Yang
256b9e94a7bSTiezhu Yang /*
257b9e94a7bSTiezhu Yang * Test stacktrace inside the kretprobe handler, this will involves
258b9e94a7bSTiezhu Yang * kretprobe trampoline, but must include correct return address
259b9e94a7bSTiezhu Yang * of the target function.
260b9e94a7bSTiezhu Yang */
261b9e94a7bSTiezhu Yang ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
262b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(current_test, ret, 0);
263b9e94a7bSTiezhu Yang
264b9e94a7bSTiezhu Yang for (i = 0; i < ret; i++) {
265b9e94a7bSTiezhu Yang if (stack_buf[i] == target_return_address[1])
266b9e94a7bSTiezhu Yang break;
267b9e94a7bSTiezhu Yang }
268b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(current_test, i, ret);
269b9e94a7bSTiezhu Yang
270b9e94a7bSTiezhu Yang #if !IS_MODULE(CONFIG_KPROBES_SANITY_TEST)
271b9e94a7bSTiezhu Yang /*
272b9e94a7bSTiezhu Yang * Test stacktrace from pt_regs at the return address. Thus the stack
273b9e94a7bSTiezhu Yang * trace must start from the target return address.
274b9e94a7bSTiezhu Yang */
275b9e94a7bSTiezhu Yang ret = stack_trace_save_regs(regs, stack_buf, STACK_BUF_SIZE, 0);
276b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(current_test, ret, 0);
277b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, stack_buf[0], target_return_address[1]);
278b9e94a7bSTiezhu Yang #endif
279b9e94a7bSTiezhu Yang
280b9e94a7bSTiezhu Yang return 0;
281b9e94a7bSTiezhu Yang }
282b9e94a7bSTiezhu Yang
283b9e94a7bSTiezhu Yang static struct kretprobe rp3 = {
284b9e94a7bSTiezhu Yang .handler = stacktrace_return_handler,
285b9e94a7bSTiezhu Yang .kp.symbol_name = "kprobe_stacktrace_target"
286b9e94a7bSTiezhu Yang };
287b9e94a7bSTiezhu Yang
test_stacktrace_on_kretprobe(struct kunit * test)288b9e94a7bSTiezhu Yang static void test_stacktrace_on_kretprobe(struct kunit *test)
289b9e94a7bSTiezhu Yang {
290b9e94a7bSTiezhu Yang unsigned long myretaddr = (unsigned long)__builtin_return_address(0);
291b9e94a7bSTiezhu Yang
292b9e94a7bSTiezhu Yang current_test = test;
293b9e94a7bSTiezhu Yang rp3.kp.addr = NULL;
294b9e94a7bSTiezhu Yang rp3.kp.flags = 0;
295b9e94a7bSTiezhu Yang
296b9e94a7bSTiezhu Yang /*
297b9e94a7bSTiezhu Yang * Run the stacktrace_driver() to record correct return address in
298b9e94a7bSTiezhu Yang * stacktrace_target() and ensure stacktrace_driver() call is not
299b9e94a7bSTiezhu Yang * inlined by checking the return address of stacktrace_driver()
300b9e94a7bSTiezhu Yang * and the return address of this function is different.
301b9e94a7bSTiezhu Yang */
302b9e94a7bSTiezhu Yang KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
303b9e94a7bSTiezhu Yang
304b9e94a7bSTiezhu Yang KUNIT_ASSERT_EQ(test, 0, register_kretprobe(&rp3));
305b9e94a7bSTiezhu Yang KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
306b9e94a7bSTiezhu Yang unregister_kretprobe(&rp3);
307b9e94a7bSTiezhu Yang }
308b9e94a7bSTiezhu Yang
stacktrace_internal_return_handler(struct kretprobe_instance * ri,struct pt_regs * regs)309b9e94a7bSTiezhu Yang static int stacktrace_internal_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
310b9e94a7bSTiezhu Yang {
311b9e94a7bSTiezhu Yang unsigned long retval = regs_return_value(regs);
312b9e94a7bSTiezhu Yang int i, ret;
313b9e94a7bSTiezhu Yang
314b9e94a7bSTiezhu Yang KUNIT_EXPECT_FALSE(current_test, preemptible());
315b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, retval, target_return_address[0]);
316b9e94a7bSTiezhu Yang
317b9e94a7bSTiezhu Yang /*
318b9e94a7bSTiezhu Yang * Test stacktrace inside the kretprobe handler for nested case.
319b9e94a7bSTiezhu Yang * The unwinder will find the kretprobe_trampoline address on the
320b9e94a7bSTiezhu Yang * return address, and kretprobe must solve that.
321b9e94a7bSTiezhu Yang */
322b9e94a7bSTiezhu Yang ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
323b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(current_test, ret, 0);
324b9e94a7bSTiezhu Yang
325b9e94a7bSTiezhu Yang for (i = 0; i < ret - 1; i++) {
326b9e94a7bSTiezhu Yang if (stack_buf[i] == target_return_address[0]) {
327b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, stack_buf[i + 1], target_return_address[1]);
328b9e94a7bSTiezhu Yang break;
329b9e94a7bSTiezhu Yang }
330b9e94a7bSTiezhu Yang }
331b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(current_test, i, ret);
332b9e94a7bSTiezhu Yang
333b9e94a7bSTiezhu Yang #if !IS_MODULE(CONFIG_KPROBES_SANITY_TEST)
334b9e94a7bSTiezhu Yang /* Ditto for the regs version. */
335b9e94a7bSTiezhu Yang ret = stack_trace_save_regs(regs, stack_buf, STACK_BUF_SIZE, 0);
336b9e94a7bSTiezhu Yang KUNIT_EXPECT_NE(current_test, ret, 0);
337b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, stack_buf[0], target_return_address[0]);
338b9e94a7bSTiezhu Yang KUNIT_EXPECT_EQ(current_test, stack_buf[1], target_return_address[1]);
339b9e94a7bSTiezhu Yang #endif
340b9e94a7bSTiezhu Yang
341b9e94a7bSTiezhu Yang return 0;
342b9e94a7bSTiezhu Yang }
343b9e94a7bSTiezhu Yang
344b9e94a7bSTiezhu Yang static struct kretprobe rp4 = {
345b9e94a7bSTiezhu Yang .handler = stacktrace_internal_return_handler,
346b9e94a7bSTiezhu Yang .kp.symbol_name = "kprobe_stacktrace_internal_target"
347b9e94a7bSTiezhu Yang };
348b9e94a7bSTiezhu Yang
test_stacktrace_on_nested_kretprobe(struct kunit * test)349b9e94a7bSTiezhu Yang static void test_stacktrace_on_nested_kretprobe(struct kunit *test)
350b9e94a7bSTiezhu Yang {
351b9e94a7bSTiezhu Yang unsigned long myretaddr = (unsigned long)__builtin_return_address(0);
352b9e94a7bSTiezhu Yang struct kretprobe *rps[2] = {&rp3, &rp4};
353b9e94a7bSTiezhu Yang
354b9e94a7bSTiezhu Yang current_test = test;
355b9e94a7bSTiezhu Yang rp3.kp.addr = NULL;
356b9e94a7bSTiezhu Yang rp3.kp.flags = 0;
357b9e94a7bSTiezhu Yang
358b9e94a7bSTiezhu Yang //KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
359b9e94a7bSTiezhu Yang
360b9e94a7bSTiezhu Yang KUNIT_ASSERT_EQ(test, 0, register_kretprobes(rps, 2));
361b9e94a7bSTiezhu Yang KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
362b9e94a7bSTiezhu Yang unregister_kretprobes(rps, 2);
363b9e94a7bSTiezhu Yang }
364b9e94a7bSTiezhu Yang #endif /* CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE */
365b9e94a7bSTiezhu Yang
366b9e94a7bSTiezhu Yang #endif /* CONFIG_KRETPROBES */
367b9e94a7bSTiezhu Yang
kprobes_test_init(struct kunit * test)368b9e94a7bSTiezhu Yang static int kprobes_test_init(struct kunit *test)
369b9e94a7bSTiezhu Yang {
370b9e94a7bSTiezhu Yang target = kprobe_target;
371b9e94a7bSTiezhu Yang target2 = kprobe_target2;
372*1fcd09fdSMasami Hiramatsu (Google) recursed_target = kprobe_recursed_target;
373b9e94a7bSTiezhu Yang stacktrace_target = kprobe_stacktrace_target;
374b9e94a7bSTiezhu Yang internal_target = kprobe_stacktrace_internal_target;
375b9e94a7bSTiezhu Yang stacktrace_driver = kprobe_stacktrace_driver;
376d247aabdSJason A. Donenfeld rand1 = get_random_u32_above(div_factor);
377b9e94a7bSTiezhu Yang return 0;
378b9e94a7bSTiezhu Yang }
379b9e94a7bSTiezhu Yang
380b9e94a7bSTiezhu Yang static struct kunit_case kprobes_testcases[] = {
381b9e94a7bSTiezhu Yang KUNIT_CASE(test_kprobe),
382b9e94a7bSTiezhu Yang KUNIT_CASE(test_kprobes),
383*1fcd09fdSMasami Hiramatsu (Google) KUNIT_CASE(test_kprobe_missed),
384b9e94a7bSTiezhu Yang #ifdef CONFIG_KRETPROBES
385b9e94a7bSTiezhu Yang KUNIT_CASE(test_kretprobe),
386b9e94a7bSTiezhu Yang KUNIT_CASE(test_kretprobes),
387b9e94a7bSTiezhu Yang #ifdef CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
388b9e94a7bSTiezhu Yang KUNIT_CASE(test_stacktrace_on_kretprobe),
389b9e94a7bSTiezhu Yang KUNIT_CASE(test_stacktrace_on_nested_kretprobe),
390b9e94a7bSTiezhu Yang #endif
391b9e94a7bSTiezhu Yang #endif
392b9e94a7bSTiezhu Yang {}
393b9e94a7bSTiezhu Yang };
394b9e94a7bSTiezhu Yang
395b9e94a7bSTiezhu Yang static struct kunit_suite kprobes_test_suite = {
396b9e94a7bSTiezhu Yang .name = "kprobes_test",
397b9e94a7bSTiezhu Yang .init = kprobes_test_init,
398b9e94a7bSTiezhu Yang .test_cases = kprobes_testcases,
399b9e94a7bSTiezhu Yang };
400b9e94a7bSTiezhu Yang
401b9e94a7bSTiezhu Yang kunit_test_suites(&kprobes_test_suite);
402b9e94a7bSTiezhu Yang
403b9e94a7bSTiezhu Yang MODULE_LICENSE("GPL");
404