Blame view

kernel/test_kprobes.c 5.92 KB
7170066ec   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
2
3
4
5
  /*
   * test_kprobes.c - simple sanity test for *probes
   *
   * Copyright IBM Corp. 2008
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
6
   */
4878b14b4   Fabian Frederick   kernel/test_kprob...
7
  #define pr_fmt(fmt) "Kprobe smoke test: " fmt
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
8
9
10
11
12
  #include <linux/kernel.h>
  #include <linux/kprobes.h>
  #include <linux/random.h>
  
  #define div_factor 3
2c7d662e2   Masami Hiramatsu   kprobes: Disable ...
13
  static u32 rand1, preh_val, posth_val;
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
14
  static int errors, handler_errors, num_tests;
8e1144050   Masami Hiramatsu   kprobes: indirect...
15
  static u32 (*target)(u32 value);
12da3b888   Masami Hiramatsu   kprobes: add test...
16
  static u32 (*target2)(u32 value);
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
17
18
19
  
  static noinline u32 kprobe_target(u32 value)
  {
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
20
21
22
23
24
  	return (value / div_factor);
  }
  
  static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
  {
3539d0915   Masami Hiramatsu   kprobes: Improve ...
25
26
27
28
29
  	if (preemptible()) {
  		handler_errors++;
  		pr_err("pre-handler is preemptible
  ");
  	}
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
30
31
32
33
34
35
36
  	preh_val = (rand1 / div_factor);
  	return 0;
  }
  
  static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
  		unsigned long flags)
  {
3539d0915   Masami Hiramatsu   kprobes: Improve ...
37
38
39
40
41
  	if (preemptible()) {
  		handler_errors++;
  		pr_err("post-handler is preemptible
  ");
  	}
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
42
43
  	if (preh_val != (rand1 / div_factor)) {
  		handler_errors++;
4878b14b4   Fabian Frederick   kernel/test_kprob...
44
45
  		pr_err("incorrect value in post_handler
  ");
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  	}
  	posth_val = preh_val + div_factor;
  }
  
  static struct kprobe kp = {
  	.symbol_name = "kprobe_target",
  	.pre_handler = kp_pre_handler,
  	.post_handler = kp_post_handler
  };
  
  static int test_kprobe(void)
  {
  	int ret;
  
  	ret = register_kprobe(&kp);
  	if (ret < 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
62
63
  		pr_err("register_kprobe returned %d
  ", ret);
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
64
65
  		return ret;
  	}
8e1144050   Masami Hiramatsu   kprobes: indirect...
66
  	ret = target(rand1);
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
67
68
69
  	unregister_kprobe(&kp);
  
  	if (preh_val == 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
70
71
  		pr_err("kprobe pre_handler not called
  ");
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
72
73
74
75
  		handler_errors++;
  	}
  
  	if (posth_val == 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
76
77
  		pr_err("kprobe post_handler not called
  ");
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
78
79
80
81
82
  		handler_errors++;
  	}
  
  	return 0;
  }
12da3b888   Masami Hiramatsu   kprobes: add test...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  static noinline u32 kprobe_target2(u32 value)
  {
  	return (value / div_factor) + 1;
  }
  
  static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
  {
  	preh_val = (rand1 / div_factor) + 1;
  	return 0;
  }
  
  static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
  		unsigned long flags)
  {
  	if (preh_val != (rand1 / div_factor) + 1) {
  		handler_errors++;
4878b14b4   Fabian Frederick   kernel/test_kprob...
99
100
  		pr_err("incorrect value in post_handler2
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  	}
  	posth_val = preh_val + div_factor;
  }
  
  static struct kprobe kp2 = {
  	.symbol_name = "kprobe_target2",
  	.pre_handler = kp_pre_handler2,
  	.post_handler = kp_post_handler2
  };
  
  static int test_kprobes(void)
  {
  	int ret;
  	struct kprobe *kps[2] = {&kp, &kp2};
fd02e6f7a   Masami Hiramatsu   kprobes: Fix self...
115
116
117
  	/* addr and flags should be cleard for reusing kprobe. */
  	kp.addr = NULL;
  	kp.flags = 0;
12da3b888   Masami Hiramatsu   kprobes: add test...
118
119
  	ret = register_kprobes(kps, 2);
  	if (ret < 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
120
121
  		pr_err("register_kprobes returned %d
  ", ret);
12da3b888   Masami Hiramatsu   kprobes: add test...
122
123
124
125
126
127
128
129
  		return ret;
  	}
  
  	preh_val = 0;
  	posth_val = 0;
  	ret = target(rand1);
  
  	if (preh_val == 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
130
131
  		pr_err("kprobe pre_handler not called
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
132
133
134
135
  		handler_errors++;
  	}
  
  	if (posth_val == 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
136
137
  		pr_err("kprobe post_handler not called
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
138
139
140
141
142
143
144
145
  		handler_errors++;
  	}
  
  	preh_val = 0;
  	posth_val = 0;
  	ret = target2(rand1);
  
  	if (preh_val == 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
146
147
  		pr_err("kprobe pre_handler2 not called
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
148
149
150
151
  		handler_errors++;
  	}
  
  	if (posth_val == 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
152
153
  		pr_err("kprobe post_handler2 not called
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
154
155
156
157
158
159
160
  		handler_errors++;
  	}
  
  	unregister_kprobes(kps, 2);
  	return 0;
  
  }
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
161
162
  #ifdef CONFIG_KRETPROBES
  static u32 krph_val;
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
163
164
  static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  {
3539d0915   Masami Hiramatsu   kprobes: Improve ...
165
166
167
168
169
  	if (preemptible()) {
  		handler_errors++;
  		pr_err("kretprobe entry handler is preemptible
  ");
  	}
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
170
171
172
  	krph_val = (rand1 / div_factor);
  	return 0;
  }
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
173
174
175
  static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  {
  	unsigned long ret = regs_return_value(regs);
3539d0915   Masami Hiramatsu   kprobes: Improve ...
176
177
178
179
180
  	if (preemptible()) {
  		handler_errors++;
  		pr_err("kretprobe return handler is preemptible
  ");
  	}
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
181
182
  	if (ret != (rand1 / div_factor)) {
  		handler_errors++;
4878b14b4   Fabian Frederick   kernel/test_kprob...
183
184
  		pr_err("incorrect value in kretprobe handler
  ");
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
185
  	}
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
186
187
  	if (krph_val == 0) {
  		handler_errors++;
4878b14b4   Fabian Frederick   kernel/test_kprob...
188
189
  		pr_err("call to kretprobe entry handler failed
  ");
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
190
  	}
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
191

f47cd9b55   Abhishek Sagar   kprobes: kretprob...
192
  	krph_val = rand1;
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
193
194
195
196
197
  	return 0;
  }
  
  static struct kretprobe rp = {
  	.handler	= return_handler,
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
198
  	.entry_handler  = entry_handler,
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
199
200
201
202
203
204
205
206
207
  	.kp.symbol_name = "kprobe_target"
  };
  
  static int test_kretprobe(void)
  {
  	int ret;
  
  	ret = register_kretprobe(&rp);
  	if (ret < 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
208
209
  		pr_err("register_kretprobe returned %d
  ", ret);
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
210
211
  		return ret;
  	}
8e1144050   Masami Hiramatsu   kprobes: indirect...
212
  	ret = target(rand1);
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
213
  	unregister_kretprobe(&rp);
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
214
  	if (krph_val != rand1) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
215
216
  		pr_err("kretprobe handler not called
  ");
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
217
218
219
220
221
  		handler_errors++;
  	}
  
  	return 0;
  }
12da3b888   Masami Hiramatsu   kprobes: add test...
222
223
224
225
226
227
228
  
  static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
  {
  	unsigned long ret = regs_return_value(regs);
  
  	if (ret != (rand1 / div_factor) + 1) {
  		handler_errors++;
4878b14b4   Fabian Frederick   kernel/test_kprob...
229
230
  		pr_err("incorrect value in kretprobe handler2
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
231
232
233
  	}
  	if (krph_val == 0) {
  		handler_errors++;
4878b14b4   Fabian Frederick   kernel/test_kprob...
234
235
  		pr_err("call to kretprobe entry handler failed
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
  	}
  
  	krph_val = rand1;
  	return 0;
  }
  
  static struct kretprobe rp2 = {
  	.handler	= return_handler2,
  	.entry_handler  = entry_handler,
  	.kp.symbol_name = "kprobe_target2"
  };
  
  static int test_kretprobes(void)
  {
  	int ret;
  	struct kretprobe *rps[2] = {&rp, &rp2};
fd02e6f7a   Masami Hiramatsu   kprobes: Fix self...
252
253
254
  	/* addr and flags should be cleard for reusing kprobe. */
  	rp.kp.addr = NULL;
  	rp.kp.flags = 0;
12da3b888   Masami Hiramatsu   kprobes: add test...
255
256
  	ret = register_kretprobes(rps, 2);
  	if (ret < 0) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
257
258
  		pr_err("register_kretprobe returned %d
  ", ret);
12da3b888   Masami Hiramatsu   kprobes: add test...
259
260
261
262
263
264
  		return ret;
  	}
  
  	krph_val = 0;
  	ret = target(rand1);
  	if (krph_val != rand1) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
265
266
  		pr_err("kretprobe handler not called
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
267
268
269
270
271
272
  		handler_errors++;
  	}
  
  	krph_val = 0;
  	ret = target2(rand1);
  	if (krph_val != rand1) {
4878b14b4   Fabian Frederick   kernel/test_kprob...
273
274
  		pr_err("kretprobe handler2 not called
  ");
12da3b888   Masami Hiramatsu   kprobes: add test...
275
276
277
278
279
  		handler_errors++;
  	}
  	unregister_kretprobes(rps, 2);
  	return 0;
  }
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
280
281
282
283
284
  #endif /* CONFIG_KRETPROBES */
  
  int init_test_probes(void)
  {
  	int ret;
8e1144050   Masami Hiramatsu   kprobes: indirect...
285
  	target = kprobe_target;
12da3b888   Masami Hiramatsu   kprobes: add test...
286
  	target2 = kprobe_target2;
8e1144050   Masami Hiramatsu   kprobes: indirect...
287

8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
288
  	do {
6d65df332   Akinobu Mita   kernel/: rename r...
289
  		rand1 = prandom_u32();
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
290
  	} while (rand1 <= div_factor);
4878b14b4   Fabian Frederick   kernel/test_kprob...
291
292
  	pr_info("started
  ");
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
293
294
295
296
297
298
  	num_tests++;
  	ret = test_kprobe();
  	if (ret < 0)
  		errors++;
  
  	num_tests++;
12da3b888   Masami Hiramatsu   kprobes: add test...
299
300
301
  	ret = test_kprobes();
  	if (ret < 0)
  		errors++;
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
302
303
304
305
306
  #ifdef CONFIG_KRETPROBES
  	num_tests++;
  	ret = test_kretprobe();
  	if (ret < 0)
  		errors++;
12da3b888   Masami Hiramatsu   kprobes: add test...
307
308
309
310
311
  
  	num_tests++;
  	ret = test_kretprobes();
  	if (ret < 0)
  		errors++;
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
312
313
314
  #endif /* CONFIG_KRETPROBES */
  
  	if (errors)
4878b14b4   Fabian Frederick   kernel/test_kprob...
315
316
  		pr_err("BUG: %d out of %d tests failed
  ", errors, num_tests);
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
317
  	else if (handler_errors)
4878b14b4   Fabian Frederick   kernel/test_kprob...
318
319
  		pr_err("BUG: %d error(s) running handlers
  ", handler_errors);
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
320
  	else
4878b14b4   Fabian Frederick   kernel/test_kprob...
321
322
  		pr_info("passed successfully
  ");
8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
323
324
325
  
  	return 0;
  }