Merge branch 'acpi-pm'
[platform/kernel/linux-starfive.git] / kernel / test_kprobes.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * test_kprobes.c - simple sanity test for *probes
4  *
5  * Copyright IBM Corp. 2008
6  */
7
8 #define pr_fmt(fmt) "Kprobe smoke test: " fmt
9
10 #include <linux/kernel.h>
11 #include <linux/kprobes.h>
12 #include <linux/random.h>
13
14 #define div_factor 3
15
16 static u32 rand1, preh_val, posth_val;
17 static int errors, handler_errors, num_tests;
18 static u32 (*target)(u32 value);
19 static u32 (*target2)(u32 value);
20
21 static noinline u32 kprobe_target(u32 value)
22 {
23         return (value / div_factor);
24 }
25
26 static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
27 {
28         if (preemptible()) {
29                 handler_errors++;
30                 pr_err("pre-handler is preemptible\n");
31         }
32         preh_val = (rand1 / div_factor);
33         return 0;
34 }
35
36 static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
37                 unsigned long flags)
38 {
39         if (preemptible()) {
40                 handler_errors++;
41                 pr_err("post-handler is preemptible\n");
42         }
43         if (preh_val != (rand1 / div_factor)) {
44                 handler_errors++;
45                 pr_err("incorrect value in post_handler\n");
46         }
47         posth_val = preh_val + div_factor;
48 }
49
50 static struct kprobe kp = {
51         .symbol_name = "kprobe_target",
52         .pre_handler = kp_pre_handler,
53         .post_handler = kp_post_handler
54 };
55
56 static int test_kprobe(void)
57 {
58         int ret;
59
60         ret = register_kprobe(&kp);
61         if (ret < 0) {
62                 pr_err("register_kprobe returned %d\n", ret);
63                 return ret;
64         }
65
66         ret = target(rand1);
67         unregister_kprobe(&kp);
68
69         if (preh_val == 0) {
70                 pr_err("kprobe pre_handler not called\n");
71                 handler_errors++;
72         }
73
74         if (posth_val == 0) {
75                 pr_err("kprobe post_handler not called\n");
76                 handler_errors++;
77         }
78
79         return 0;
80 }
81
82 static noinline u32 kprobe_target2(u32 value)
83 {
84         return (value / div_factor) + 1;
85 }
86
87 static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
88 {
89         preh_val = (rand1 / div_factor) + 1;
90         return 0;
91 }
92
93 static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
94                 unsigned long flags)
95 {
96         if (preh_val != (rand1 / div_factor) + 1) {
97                 handler_errors++;
98                 pr_err("incorrect value in post_handler2\n");
99         }
100         posth_val = preh_val + div_factor;
101 }
102
103 static struct kprobe kp2 = {
104         .symbol_name = "kprobe_target2",
105         .pre_handler = kp_pre_handler2,
106         .post_handler = kp_post_handler2
107 };
108
109 static int test_kprobes(void)
110 {
111         int ret;
112         struct kprobe *kps[2] = {&kp, &kp2};
113
114         /* addr and flags should be cleard for reusing kprobe. */
115         kp.addr = NULL;
116         kp.flags = 0;
117         ret = register_kprobes(kps, 2);
118         if (ret < 0) {
119                 pr_err("register_kprobes returned %d\n", ret);
120                 return ret;
121         }
122
123         preh_val = 0;
124         posth_val = 0;
125         ret = target(rand1);
126
127         if (preh_val == 0) {
128                 pr_err("kprobe pre_handler not called\n");
129                 handler_errors++;
130         }
131
132         if (posth_val == 0) {
133                 pr_err("kprobe post_handler not called\n");
134                 handler_errors++;
135         }
136
137         preh_val = 0;
138         posth_val = 0;
139         ret = target2(rand1);
140
141         if (preh_val == 0) {
142                 pr_err("kprobe pre_handler2 not called\n");
143                 handler_errors++;
144         }
145
146         if (posth_val == 0) {
147                 pr_err("kprobe post_handler2 not called\n");
148                 handler_errors++;
149         }
150
151         unregister_kprobes(kps, 2);
152         return 0;
153
154 }
155
156 #ifdef CONFIG_KRETPROBES
157 static u32 krph_val;
158
159 static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
160 {
161         if (preemptible()) {
162                 handler_errors++;
163                 pr_err("kretprobe entry handler is preemptible\n");
164         }
165         krph_val = (rand1 / div_factor);
166         return 0;
167 }
168
169 static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
170 {
171         unsigned long ret = regs_return_value(regs);
172
173         if (preemptible()) {
174                 handler_errors++;
175                 pr_err("kretprobe return handler is preemptible\n");
176         }
177         if (ret != (rand1 / div_factor)) {
178                 handler_errors++;
179                 pr_err("incorrect value in kretprobe handler\n");
180         }
181         if (krph_val == 0) {
182                 handler_errors++;
183                 pr_err("call to kretprobe entry handler failed\n");
184         }
185
186         krph_val = rand1;
187         return 0;
188 }
189
190 static struct kretprobe rp = {
191         .handler        = return_handler,
192         .entry_handler  = entry_handler,
193         .kp.symbol_name = "kprobe_target"
194 };
195
196 static int test_kretprobe(void)
197 {
198         int ret;
199
200         ret = register_kretprobe(&rp);
201         if (ret < 0) {
202                 pr_err("register_kretprobe returned %d\n", ret);
203                 return ret;
204         }
205
206         ret = target(rand1);
207         unregister_kretprobe(&rp);
208         if (krph_val != rand1) {
209                 pr_err("kretprobe handler not called\n");
210                 handler_errors++;
211         }
212
213         return 0;
214 }
215
216 static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
217 {
218         unsigned long ret = regs_return_value(regs);
219
220         if (ret != (rand1 / div_factor) + 1) {
221                 handler_errors++;
222                 pr_err("incorrect value in kretprobe handler2\n");
223         }
224         if (krph_val == 0) {
225                 handler_errors++;
226                 pr_err("call to kretprobe entry handler failed\n");
227         }
228
229         krph_val = rand1;
230         return 0;
231 }
232
233 static struct kretprobe rp2 = {
234         .handler        = return_handler2,
235         .entry_handler  = entry_handler,
236         .kp.symbol_name = "kprobe_target2"
237 };
238
239 static int test_kretprobes(void)
240 {
241         int ret;
242         struct kretprobe *rps[2] = {&rp, &rp2};
243
244         /* addr and flags should be cleard for reusing kprobe. */
245         rp.kp.addr = NULL;
246         rp.kp.flags = 0;
247         ret = register_kretprobes(rps, 2);
248         if (ret < 0) {
249                 pr_err("register_kretprobe returned %d\n", ret);
250                 return ret;
251         }
252
253         krph_val = 0;
254         ret = target(rand1);
255         if (krph_val != rand1) {
256                 pr_err("kretprobe handler not called\n");
257                 handler_errors++;
258         }
259
260         krph_val = 0;
261         ret = target2(rand1);
262         if (krph_val != rand1) {
263                 pr_err("kretprobe handler2 not called\n");
264                 handler_errors++;
265         }
266         unregister_kretprobes(rps, 2);
267         return 0;
268 }
269 #endif /* CONFIG_KRETPROBES */
270
271 int init_test_probes(void)
272 {
273         int ret;
274
275         target = kprobe_target;
276         target2 = kprobe_target2;
277
278         do {
279                 rand1 = prandom_u32();
280         } while (rand1 <= div_factor);
281
282         pr_info("started\n");
283         num_tests++;
284         ret = test_kprobe();
285         if (ret < 0)
286                 errors++;
287
288         num_tests++;
289         ret = test_kprobes();
290         if (ret < 0)
291                 errors++;
292
293 #ifdef CONFIG_KRETPROBES
294         num_tests++;
295         ret = test_kretprobe();
296         if (ret < 0)
297                 errors++;
298
299         num_tests++;
300         ret = test_kretprobes();
301         if (ret < 0)
302                 errors++;
303 #endif /* CONFIG_KRETPROBES */
304
305         if (errors)
306                 pr_err("BUG: %d out of %d tests failed\n", errors, num_tests);
307         else if (handler_errors)
308                 pr_err("BUG: %d error(s) running handlers\n", handler_errors);
309         else
310                 pr_info("passed successfully\n");
311
312         return 0;
313 }