kprobes: convert tests to kunit
[linux-2.6-block.git] / kernel / test_kprobes.c
CommitLineData
7170066e 1// SPDX-License-Identifier: GPL-2.0-or-later
8c1c9356
AM
2/*
3 * test_kprobes.c - simple sanity test for *probes
4 *
5 * Copyright IBM Corp. 2008
8c1c9356
AM
6 */
7
8#include <linux/kernel.h>
9#include <linux/kprobes.h>
10#include <linux/random.h>
e44e81c5 11#include <kunit/test.h>
8c1c9356
AM
12
13#define div_factor 3
14
2c7d662e 15static u32 rand1, preh_val, posth_val;
8e114405 16static u32 (*target)(u32 value);
12da3b88 17static u32 (*target2)(u32 value);
e44e81c5 18static struct kunit *current_test;
8c1c9356
AM
19
20static noinline u32 kprobe_target(u32 value)
21{
8c1c9356
AM
22 return (value / div_factor);
23}
24
25static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
26{
e44e81c5 27 KUNIT_EXPECT_FALSE(current_test, preemptible());
8c1c9356
AM
28 preh_val = (rand1 / div_factor);
29 return 0;
30}
31
32static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
33 unsigned long flags)
34{
e44e81c5
SS
35 KUNIT_EXPECT_FALSE(current_test, preemptible());
36 KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor));
8c1c9356
AM
37 posth_val = preh_val + div_factor;
38}
39
40static struct kprobe kp = {
41 .symbol_name = "kprobe_target",
42 .pre_handler = kp_pre_handler,
43 .post_handler = kp_post_handler
44};
45
e44e81c5 46static void test_kprobe(struct kunit *test)
8c1c9356 47{
e44e81c5
SS
48 current_test = test;
49 KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp));
50 target(rand1);
8c1c9356 51 unregister_kprobe(&kp);
e44e81c5
SS
52 KUNIT_EXPECT_NE(test, 0, preh_val);
53 KUNIT_EXPECT_NE(test, 0, posth_val);
8c1c9356
AM
54}
55
12da3b88
MH
56static noinline u32 kprobe_target2(u32 value)
57{
58 return (value / div_factor) + 1;
59}
60
61static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
62{
63 preh_val = (rand1 / div_factor) + 1;
64 return 0;
65}
66
67static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
68 unsigned long flags)
69{
e44e81c5 70 KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor) + 1);
12da3b88
MH
71 posth_val = preh_val + div_factor;
72}
73
74static struct kprobe kp2 = {
75 .symbol_name = "kprobe_target2",
76 .pre_handler = kp_pre_handler2,
77 .post_handler = kp_post_handler2
78};
79
e44e81c5 80static void test_kprobes(struct kunit *test)
12da3b88 81{
12da3b88
MH
82 struct kprobe *kps[2] = {&kp, &kp2};
83
e44e81c5
SS
84 current_test = test;
85
fd02e6f7
MH
86 /* addr and flags should be cleard for reusing kprobe. */
87 kp.addr = NULL;
88 kp.flags = 0;
12da3b88 89
e44e81c5 90 KUNIT_EXPECT_EQ(test, 0, register_kprobes(kps, 2));
12da3b88
MH
91 preh_val = 0;
92 posth_val = 0;
e44e81c5 93 target(rand1);
12da3b88 94
e44e81c5
SS
95 KUNIT_EXPECT_NE(test, 0, preh_val);
96 KUNIT_EXPECT_NE(test, 0, posth_val);
12da3b88
MH
97
98 preh_val = 0;
99 posth_val = 0;
e44e81c5 100 target2(rand1);
12da3b88 101
e44e81c5
SS
102 KUNIT_EXPECT_NE(test, 0, preh_val);
103 KUNIT_EXPECT_NE(test, 0, posth_val);
12da3b88 104 unregister_kprobes(kps, 2);
12da3b88
MH
105}
106
8c1c9356
AM
107#ifdef CONFIG_KRETPROBES
108static u32 krph_val;
109
f47cd9b5
AS
110static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
111{
e44e81c5 112 KUNIT_EXPECT_FALSE(current_test, preemptible());
f47cd9b5
AS
113 krph_val = (rand1 / div_factor);
114 return 0;
115}
116
8c1c9356
AM
117static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
118{
119 unsigned long ret = regs_return_value(regs);
120
e44e81c5
SS
121 KUNIT_EXPECT_FALSE(current_test, preemptible());
122 KUNIT_EXPECT_EQ(current_test, ret, rand1 / div_factor);
123 KUNIT_EXPECT_NE(current_test, krph_val, 0);
f47cd9b5 124 krph_val = rand1;
8c1c9356
AM
125 return 0;
126}
127
128static struct kretprobe rp = {
129 .handler = return_handler,
f47cd9b5 130 .entry_handler = entry_handler,
8c1c9356
AM
131 .kp.symbol_name = "kprobe_target"
132};
133
e44e81c5 134static void test_kretprobe(struct kunit *test)
8c1c9356 135{
e44e81c5
SS
136 current_test = test;
137 KUNIT_EXPECT_EQ(test, 0, register_kretprobe(&rp));
138 target(rand1);
8c1c9356 139 unregister_kretprobe(&rp);
e44e81c5 140 KUNIT_EXPECT_EQ(test, krph_val, rand1);
8c1c9356 141}
12da3b88
MH
142
143static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
144{
145 unsigned long ret = regs_return_value(regs);
146
e44e81c5
SS
147 KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
148 KUNIT_EXPECT_NE(current_test, krph_val, 0);
12da3b88
MH
149 krph_val = rand1;
150 return 0;
151}
152
153static struct kretprobe rp2 = {
154 .handler = return_handler2,
155 .entry_handler = entry_handler,
156 .kp.symbol_name = "kprobe_target2"
157};
158
e44e81c5 159static void test_kretprobes(struct kunit *test)
12da3b88 160{
12da3b88
MH
161 struct kretprobe *rps[2] = {&rp, &rp2};
162
e44e81c5 163 current_test = test;
fd02e6f7
MH
164 /* addr and flags should be cleard for reusing kprobe. */
165 rp.kp.addr = NULL;
166 rp.kp.flags = 0;
e44e81c5 167 KUNIT_EXPECT_EQ(test, 0, register_kretprobes(rps, 2));
12da3b88
MH
168
169 krph_val = 0;
e44e81c5
SS
170 target(rand1);
171 KUNIT_EXPECT_EQ(test, krph_val, rand1);
12da3b88
MH
172
173 krph_val = 0;
e44e81c5
SS
174 target2(rand1);
175 KUNIT_EXPECT_EQ(test, krph_val, rand1);
12da3b88 176 unregister_kretprobes(rps, 2);
12da3b88 177}
8c1c9356
AM
178#endif /* CONFIG_KRETPROBES */
179
e44e81c5 180static int kprobes_test_init(struct kunit *test)
8c1c9356 181{
8e114405 182 target = kprobe_target;
12da3b88 183 target2 = kprobe_target2;
8e114405 184
8c1c9356 185 do {
6d65df33 186 rand1 = prandom_u32();
8c1c9356 187 } while (rand1 <= div_factor);
e44e81c5
SS
188 return 0;
189}
8c1c9356 190
e44e81c5
SS
191static struct kunit_case kprobes_testcases[] = {
192 KUNIT_CASE(test_kprobe),
193 KUNIT_CASE(test_kprobes),
8c1c9356 194#ifdef CONFIG_KRETPROBES
e44e81c5
SS
195 KUNIT_CASE(test_kretprobe),
196 KUNIT_CASE(test_kretprobes),
197#endif
198 {}
199};
8c1c9356 200
e44e81c5
SS
201static struct kunit_suite kprobes_test_suite = {
202 .name = "kprobes_test",
203 .init = kprobes_test_init,
204 .test_cases = kprobes_testcases,
205};
8c1c9356 206
e44e81c5
SS
207kunit_test_suites(&kprobes_test_suite);
208
209MODULE_LICENSE("GPL");