Commit | Line | Data |
---|---|---|
9eed1797 JM |
1 | /* |
2 | * arch/arm/kernel/kprobes-test.c | |
3 | * | |
4 | * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | */ | |
10 | ||
a43bc69b JM |
11 | /* |
12 | * TESTING METHODOLOGY | |
13 | * ------------------- | |
14 | * | |
15 | * The methodology used to test an ARM instruction 'test_insn' is to use | |
16 | * inline assembler like: | |
17 | * | |
18 | * test_before: nop | |
19 | * test_case: test_insn | |
20 | * test_after: nop | |
21 | * | |
22 | * When the test case is run a kprobe is placed of each nop. The | |
23 | * post-handler of the test_before probe is used to modify the saved CPU | |
24 | * register context to that which we require for the test case. The | |
25 | * pre-handler of the of the test_after probe saves a copy of the CPU | |
26 | * register context. In this way we can execute test_insn with a specific | |
27 | * register context and see the results afterwards. | |
28 | * | |
29 | * To actually test the kprobes instruction emulation we perform the above | |
30 | * step a second time but with an additional kprobe on the test_case | |
31 | * instruction itself. If the emulation is accurate then the results seen | |
32 | * by the test_after probe will be identical to the first run which didn't | |
33 | * have a probe on test_case. | |
34 | * | |
35 | * Each test case is run several times with a variety of variations in the | |
36 | * flags value of stored in CPSR, and for Thumb code, different ITState. | |
37 | * | |
38 | * For instructions which can modify PC, a second test_after probe is used | |
39 | * like this: | |
40 | * | |
41 | * test_before: nop | |
42 | * test_case: test_insn | |
43 | * test_after: nop | |
44 | * b test_done | |
45 | * test_after2: nop | |
46 | * test_done: | |
47 | * | |
48 | * The test case is constructed such that test_insn branches to | |
49 | * test_after2, or, if testing a conditional instruction, it may just | |
50 | * continue to test_after. The probes inserted at both locations let us | |
51 | * determine which happened. A similar approach is used for testing | |
52 | * backwards branches... | |
53 | * | |
54 | * b test_before | |
55 | * b test_done @ helps to cope with off by 1 branches | |
56 | * test_after2: nop | |
57 | * b test_done | |
58 | * test_before: nop | |
59 | * test_case: test_insn | |
60 | * test_after: nop | |
61 | * test_done: | |
62 | * | |
63 | * The macros used to generate the assembler instructions describe above | |
64 | * are TEST_INSTRUCTION, TEST_BRANCH_F (branch forwards) and TEST_BRANCH_B | |
65 | * (branch backwards). In these, the local variables numbered 1, 50, 2 and | |
66 | * 99 represent: test_before, test_case, test_after2 and test_done. | |
67 | * | |
68 | * FRAMEWORK | |
69 | * --------- | |
70 | * | |
71 | * Each test case is wrapped between the pair of macros TESTCASE_START and | |
72 | * TESTCASE_END. As well as performing the inline assembler boilerplate, | |
73 | * these call out to the kprobes_test_case_start() and | |
74 | * kprobes_test_case_end() functions which drive the execution of the test | |
75 | * case. The specific arguments to use for each test case are stored as | |
76 | * inline data constructed using the various TEST_ARG_* macros. Putting | |
77 | * this all together, a simple test case may look like: | |
78 | * | |
79 | * TESTCASE_START("Testing mov r0, r7") | |
80 | * TEST_ARG_REG(7, 0x12345678) // Set r7=0x12345678 | |
81 | * TEST_ARG_END("") | |
82 | * TEST_INSTRUCTION("mov r0, r7") | |
83 | * TESTCASE_END | |
84 | * | |
85 | * Note, in practice the single convenience macro TEST_R would be used for this | |
86 | * instead. | |
87 | * | |
88 | * The above would expand to assembler looking something like: | |
89 | * | |
90 | * @ TESTCASE_START | |
91 | * bl __kprobes_test_case_start | |
92 | * @ start of inline data... | |
93 | * .ascii "mov r0, r7" @ text title for test case | |
94 | * .byte 0 | |
95 | * .align 2 | |
96 | * | |
97 | * @ TEST_ARG_REG | |
98 | * .byte ARG_TYPE_REG | |
99 | * .byte 7 | |
100 | * .short 0 | |
101 | * .word 0x1234567 | |
102 | * | |
103 | * @ TEST_ARG_END | |
104 | * .byte ARG_TYPE_END | |
105 | * .byte TEST_ISA @ flags, including ISA being tested | |
106 | * .short 50f-0f @ offset of 'test_before' | |
107 | * .short 2f-0f @ offset of 'test_after2' (if relevent) | |
108 | * .short 99f-0f @ offset of 'test_done' | |
109 | * @ start of test case code... | |
110 | * 0: | |
111 | * .code TEST_ISA @ switch to ISA being tested | |
112 | * | |
113 | * @ TEST_INSTRUCTION | |
114 | * 50: nop @ location for 'test_before' probe | |
115 | * 1: mov r0, r7 @ the test case instruction 'test_insn' | |
116 | * nop @ location for 'test_after' probe | |
117 | * | |
118 | * // TESTCASE_END | |
119 | * 2: | |
120 | * 99: bl __kprobes_test_case_end_##TEST_ISA | |
121 | * .code NONMAL_ISA | |
122 | * | |
123 | * When the above is execute the following happens... | |
124 | * | |
125 | * __kprobes_test_case_start() is an assembler wrapper which sets up space | |
126 | * for a stack buffer and calls the C function kprobes_test_case_start(). | |
127 | * This C function will do some initial processing of the inline data and | |
128 | * setup some global state. It then inserts the test_before and test_after | |
129 | * kprobes and returns a value which causes the assembler wrapper to jump | |
130 | * to the start of the test case code, (local label '0'). | |
131 | * | |
132 | * When the test case code executes, the test_before probe will be hit and | |
133 | * test_before_post_handler will call setup_test_context(). This fills the | |
134 | * stack buffer and CPU registers with a test pattern and then processes | |
135 | * the test case arguments. In our example there is one TEST_ARG_REG which | |
136 | * indicates that R7 should be loaded with the value 0x12345678. | |
137 | * | |
138 | * When the test_before probe ends, the test case continues and executes | |
139 | * the "mov r0, r7" instruction. It then hits the test_after probe and the | |
140 | * pre-handler for this (test_after_pre_handler) will save a copy of the | |
141 | * CPU register context. This should now have R0 holding the same value as | |
142 | * R7. | |
143 | * | |
144 | * Finally we get to the call to __kprobes_test_case_end_{32,16}. This is | |
145 | * an assembler wrapper which switches back to the ISA used by the test | |
146 | * code and calls the C function kprobes_test_case_end(). | |
147 | * | |
148 | * For each run through the test case, test_case_run_count is incremented | |
149 | * by one. For even runs, kprobes_test_case_end() saves a copy of the | |
150 | * register and stack buffer contents from the test case just run. It then | |
151 | * inserts a kprobe on the test case instruction 'test_insn' and returns a | |
152 | * value to cause the test case code to be re-run. | |
153 | * | |
154 | * For odd numbered runs, kprobes_test_case_end() compares the register and | |
155 | * stack buffer contents to those that were saved on the previous even | |
156 | * numbered run (the one without the kprobe on test_insn). These should be | |
157 | * the same if the kprobe instruction simulation routine is correct. | |
158 | * | |
159 | * The pair of test case runs is repeated with different combinations of | |
160 | * flag values in CPSR and, for Thumb, different ITState. This is | |
161 | * controlled by test_context_cpsr(). | |
162 | * | |
163 | * BUILDING TEST CASES | |
164 | * ------------------- | |
165 | * | |
166 | * | |
167 | * As an aid to building test cases, the stack buffer is initialised with | |
168 | * some special values: | |
169 | * | |
170 | * [SP+13*4] Contains SP+120. This can be used to test instructions | |
171 | * which load a value into SP. | |
172 | * | |
173 | * [SP+15*4] When testing branching instructions using TEST_BRANCH_{F,B}, | |
174 | * this holds the target address of the branch, 'test_after2'. | |
175 | * This can be used to test instructions which load a PC value | |
176 | * from memory. | |
177 | */ | |
178 | ||
9eed1797 JM |
179 | #include <linux/kernel.h> |
180 | #include <linux/module.h> | |
181 | #include <linux/kprobes.h> | |
182 | ||
183 | #include "kprobes.h" | |
a43bc69b | 184 | #include "kprobes-test.h" |
9eed1797 JM |
185 | |
186 | ||
187 | /* | |
188 | * Test basic API | |
189 | */ | |
190 | ||
191 | static bool test_regs_ok; | |
192 | static int test_func_instance; | |
193 | static int pre_handler_called; | |
194 | static int post_handler_called; | |
195 | static int jprobe_func_called; | |
196 | static int kretprobe_handler_called; | |
197 | ||
198 | #define FUNC_ARG1 0x12345678 | |
199 | #define FUNC_ARG2 0xabcdef | |
200 | ||
201 | ||
202 | #ifndef CONFIG_THUMB2_KERNEL | |
203 | ||
204 | long arm_func(long r0, long r1); | |
205 | ||
206 | static void __used __naked __arm_kprobes_test_func(void) | |
207 | { | |
208 | __asm__ __volatile__ ( | |
209 | ".arm \n\t" | |
210 | ".type arm_func, %%function \n\t" | |
211 | "arm_func: \n\t" | |
212 | "adds r0, r0, r1 \n\t" | |
213 | "bx lr \n\t" | |
214 | ".code "NORMAL_ISA /* Back to Thumb if necessary */ | |
215 | : : : "r0", "r1", "cc" | |
216 | ); | |
217 | } | |
218 | ||
219 | #else /* CONFIG_THUMB2_KERNEL */ | |
220 | ||
221 | long thumb16_func(long r0, long r1); | |
222 | long thumb32even_func(long r0, long r1); | |
223 | long thumb32odd_func(long r0, long r1); | |
224 | ||
225 | static void __used __naked __thumb_kprobes_test_funcs(void) | |
226 | { | |
227 | __asm__ __volatile__ ( | |
228 | ".type thumb16_func, %%function \n\t" | |
229 | "thumb16_func: \n\t" | |
230 | "adds.n r0, r0, r1 \n\t" | |
231 | "bx lr \n\t" | |
232 | ||
233 | ".align \n\t" | |
234 | ".type thumb32even_func, %%function \n\t" | |
235 | "thumb32even_func: \n\t" | |
236 | "adds.w r0, r0, r1 \n\t" | |
237 | "bx lr \n\t" | |
238 | ||
239 | ".align \n\t" | |
240 | "nop.n \n\t" | |
241 | ".type thumb32odd_func, %%function \n\t" | |
242 | "thumb32odd_func: \n\t" | |
243 | "adds.w r0, r0, r1 \n\t" | |
244 | "bx lr \n\t" | |
245 | ||
246 | : : : "r0", "r1", "cc" | |
247 | ); | |
248 | } | |
249 | ||
250 | #endif /* CONFIG_THUMB2_KERNEL */ | |
251 | ||
252 | ||
253 | static int call_test_func(long (*func)(long, long), bool check_test_regs) | |
254 | { | |
255 | long ret; | |
256 | ||
257 | ++test_func_instance; | |
258 | test_regs_ok = false; | |
259 | ||
260 | ret = (*func)(FUNC_ARG1, FUNC_ARG2); | |
261 | if (ret != FUNC_ARG1 + FUNC_ARG2) { | |
262 | pr_err("FAIL: call_test_func: func returned %lx\n", ret); | |
263 | return false; | |
264 | } | |
265 | ||
266 | if (check_test_regs && !test_regs_ok) { | |
267 | pr_err("FAIL: test regs not OK\n"); | |
268 | return false; | |
269 | } | |
270 | ||
271 | return true; | |
272 | } | |
273 | ||
274 | static int __kprobes pre_handler(struct kprobe *p, struct pt_regs *regs) | |
275 | { | |
276 | pre_handler_called = test_func_instance; | |
277 | if (regs->ARM_r0 == FUNC_ARG1 && regs->ARM_r1 == FUNC_ARG2) | |
278 | test_regs_ok = true; | |
279 | return 0; | |
280 | } | |
281 | ||
282 | static void __kprobes post_handler(struct kprobe *p, struct pt_regs *regs, | |
283 | unsigned long flags) | |
284 | { | |
285 | post_handler_called = test_func_instance; | |
286 | if (regs->ARM_r0 != FUNC_ARG1 + FUNC_ARG2 || regs->ARM_r1 != FUNC_ARG2) | |
287 | test_regs_ok = false; | |
288 | } | |
289 | ||
290 | static struct kprobe the_kprobe = { | |
291 | .addr = 0, | |
292 | .pre_handler = pre_handler, | |
293 | .post_handler = post_handler | |
294 | }; | |
295 | ||
296 | static int test_kprobe(long (*func)(long, long)) | |
297 | { | |
298 | int ret; | |
299 | ||
300 | the_kprobe.addr = (kprobe_opcode_t *)func; | |
301 | ret = register_kprobe(&the_kprobe); | |
302 | if (ret < 0) { | |
303 | pr_err("FAIL: register_kprobe failed with %d\n", ret); | |
304 | return ret; | |
305 | } | |
306 | ||
307 | ret = call_test_func(func, true); | |
308 | ||
309 | unregister_kprobe(&the_kprobe); | |
310 | the_kprobe.flags = 0; /* Clear disable flag to allow reuse */ | |
311 | ||
312 | if (!ret) | |
313 | return -EINVAL; | |
314 | if (pre_handler_called != test_func_instance) { | |
315 | pr_err("FAIL: kprobe pre_handler not called\n"); | |
316 | return -EINVAL; | |
317 | } | |
318 | if (post_handler_called != test_func_instance) { | |
319 | pr_err("FAIL: kprobe post_handler not called\n"); | |
320 | return -EINVAL; | |
321 | } | |
322 | if (!call_test_func(func, false)) | |
323 | return -EINVAL; | |
324 | if (pre_handler_called == test_func_instance || | |
325 | post_handler_called == test_func_instance) { | |
326 | pr_err("FAIL: probe called after unregistering\n"); | |
327 | return -EINVAL; | |
328 | } | |
329 | ||
330 | return 0; | |
331 | } | |
332 | ||
333 | static void __kprobes jprobe_func(long r0, long r1) | |
334 | { | |
335 | jprobe_func_called = test_func_instance; | |
336 | if (r0 == FUNC_ARG1 && r1 == FUNC_ARG2) | |
337 | test_regs_ok = true; | |
338 | jprobe_return(); | |
339 | } | |
340 | ||
341 | static struct jprobe the_jprobe = { | |
342 | .entry = jprobe_func, | |
343 | }; | |
344 | ||
345 | static int test_jprobe(long (*func)(long, long)) | |
346 | { | |
347 | int ret; | |
348 | ||
349 | the_jprobe.kp.addr = (kprobe_opcode_t *)func; | |
350 | ret = register_jprobe(&the_jprobe); | |
351 | if (ret < 0) { | |
352 | pr_err("FAIL: register_jprobe failed with %d\n", ret); | |
353 | return ret; | |
354 | } | |
355 | ||
356 | ret = call_test_func(func, true); | |
357 | ||
358 | unregister_jprobe(&the_jprobe); | |
359 | the_jprobe.kp.flags = 0; /* Clear disable flag to allow reuse */ | |
360 | ||
361 | if (!ret) | |
362 | return -EINVAL; | |
363 | if (jprobe_func_called != test_func_instance) { | |
364 | pr_err("FAIL: jprobe handler function not called\n"); | |
365 | return -EINVAL; | |
366 | } | |
367 | if (!call_test_func(func, false)) | |
368 | return -EINVAL; | |
369 | if (jprobe_func_called == test_func_instance) { | |
370 | pr_err("FAIL: probe called after unregistering\n"); | |
371 | return -EINVAL; | |
372 | } | |
373 | ||
374 | return 0; | |
375 | } | |
376 | ||
377 | static int __kprobes | |
378 | kretprobe_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | |
379 | { | |
380 | kretprobe_handler_called = test_func_instance; | |
381 | if (regs_return_value(regs) == FUNC_ARG1 + FUNC_ARG2) | |
382 | test_regs_ok = true; | |
383 | return 0; | |
384 | } | |
385 | ||
386 | static struct kretprobe the_kretprobe = { | |
387 | .handler = kretprobe_handler, | |
388 | }; | |
389 | ||
390 | static int test_kretprobe(long (*func)(long, long)) | |
391 | { | |
392 | int ret; | |
393 | ||
394 | the_kretprobe.kp.addr = (kprobe_opcode_t *)func; | |
395 | ret = register_kretprobe(&the_kretprobe); | |
396 | if (ret < 0) { | |
397 | pr_err("FAIL: register_kretprobe failed with %d\n", ret); | |
398 | return ret; | |
399 | } | |
400 | ||
401 | ret = call_test_func(func, true); | |
402 | ||
403 | unregister_kretprobe(&the_kretprobe); | |
404 | the_kretprobe.kp.flags = 0; /* Clear disable flag to allow reuse */ | |
405 | ||
406 | if (!ret) | |
407 | return -EINVAL; | |
408 | if (kretprobe_handler_called != test_func_instance) { | |
409 | pr_err("FAIL: kretprobe handler not called\n"); | |
410 | return -EINVAL; | |
411 | } | |
412 | if (!call_test_func(func, false)) | |
413 | return -EINVAL; | |
414 | if (jprobe_func_called == test_func_instance) { | |
415 | pr_err("FAIL: kretprobe called after unregistering\n"); | |
416 | return -EINVAL; | |
417 | } | |
418 | ||
419 | return 0; | |
420 | } | |
421 | ||
422 | static int run_api_tests(long (*func)(long, long)) | |
423 | { | |
424 | int ret; | |
425 | ||
426 | pr_info(" kprobe\n"); | |
427 | ret = test_kprobe(func); | |
428 | if (ret < 0) | |
429 | return ret; | |
430 | ||
431 | pr_info(" jprobe\n"); | |
432 | ret = test_jprobe(func); | |
433 | if (ret < 0) | |
434 | return ret; | |
435 | ||
436 | pr_info(" kretprobe\n"); | |
437 | ret = test_kretprobe(func); | |
438 | if (ret < 0) | |
439 | return ret; | |
440 | ||
441 | return 0; | |
442 | } | |
443 | ||
444 | ||
68f360e7 JM |
445 | /* |
446 | * Decoding table self-consistency tests | |
447 | */ | |
448 | ||
449 | static const int decode_struct_sizes[NUM_DECODE_TYPES] = { | |
450 | [DECODE_TYPE_TABLE] = sizeof(struct decode_table), | |
451 | [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom), | |
452 | [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate), | |
453 | [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate), | |
454 | [DECODE_TYPE_OR] = sizeof(struct decode_or), | |
455 | [DECODE_TYPE_REJECT] = sizeof(struct decode_reject) | |
456 | }; | |
457 | ||
458 | static int table_iter(const union decode_item *table, | |
459 | int (*fn)(const struct decode_header *, void *), | |
460 | void *args) | |
461 | { | |
462 | const struct decode_header *h = (struct decode_header *)table; | |
463 | int result; | |
464 | ||
465 | for (;;) { | |
466 | enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; | |
467 | ||
468 | if (type == DECODE_TYPE_END) | |
469 | return 0; | |
470 | ||
471 | result = fn(h, args); | |
472 | if (result) | |
473 | return result; | |
474 | ||
475 | h = (struct decode_header *) | |
476 | ((uintptr_t)h + decode_struct_sizes[type]); | |
477 | ||
478 | } | |
479 | } | |
480 | ||
481 | static int table_test_fail(const struct decode_header *h, const char* message) | |
482 | { | |
483 | ||
484 | pr_err("FAIL: kprobes test failure \"%s\" (mask %08x, value %08x)\n", | |
485 | message, h->mask.bits, h->value.bits); | |
486 | return -EINVAL; | |
487 | } | |
488 | ||
489 | struct table_test_args { | |
490 | const union decode_item *root_table; | |
491 | u32 parent_mask; | |
492 | u32 parent_value; | |
493 | }; | |
494 | ||
495 | static int table_test_fn(const struct decode_header *h, void *args) | |
496 | { | |
497 | struct table_test_args *a = (struct table_test_args *)args; | |
498 | enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; | |
499 | ||
500 | if (h->value.bits & ~h->mask.bits) | |
501 | return table_test_fail(h, "Match value has bits not in mask"); | |
502 | ||
503 | if ((h->mask.bits & a->parent_mask) != a->parent_mask) | |
504 | return table_test_fail(h, "Mask has bits not in parent mask"); | |
505 | ||
506 | if ((h->value.bits ^ a->parent_value) & a->parent_mask) | |
507 | return table_test_fail(h, "Value is inconsistent with parent"); | |
508 | ||
509 | if (type == DECODE_TYPE_TABLE) { | |
510 | struct decode_table *d = (struct decode_table *)h; | |
511 | struct table_test_args args2 = *a; | |
512 | args2.parent_mask = h->mask.bits; | |
513 | args2.parent_value = h->value.bits; | |
514 | return table_iter(d->table.table, table_test_fn, &args2); | |
515 | } | |
516 | ||
517 | return 0; | |
518 | } | |
519 | ||
520 | static int table_test(const union decode_item *table) | |
521 | { | |
522 | struct table_test_args args = { | |
523 | .root_table = table, | |
524 | .parent_mask = 0, | |
525 | .parent_value = 0 | |
526 | }; | |
527 | return table_iter(args.root_table, table_test_fn, &args); | |
528 | } | |
529 | ||
530 | ||
a43bc69b JM |
531 | /* |
532 | * Framework for instruction set test cases | |
533 | */ | |
534 | ||
535 | void __naked __kprobes_test_case_start(void) | |
536 | { | |
537 | __asm__ __volatile__ ( | |
538 | "stmdb sp!, {r4-r11} \n\t" | |
539 | "sub sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" | |
540 | "bic r0, lr, #1 @ r0 = inline title string \n\t" | |
541 | "mov r1, sp \n\t" | |
542 | "bl kprobes_test_case_start \n\t" | |
543 | "bx r0 \n\t" | |
544 | ); | |
545 | } | |
546 | ||
547 | #ifndef CONFIG_THUMB2_KERNEL | |
548 | ||
549 | void __naked __kprobes_test_case_end_32(void) | |
550 | { | |
551 | __asm__ __volatile__ ( | |
552 | "mov r4, lr \n\t" | |
553 | "bl kprobes_test_case_end \n\t" | |
554 | "cmp r0, #0 \n\t" | |
555 | "movne pc, r0 \n\t" | |
556 | "mov r0, r4 \n\t" | |
557 | "add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" | |
558 | "ldmia sp!, {r4-r11} \n\t" | |
559 | "mov pc, r0 \n\t" | |
560 | ); | |
561 | } | |
562 | ||
563 | #else /* CONFIG_THUMB2_KERNEL */ | |
564 | ||
565 | void __naked __kprobes_test_case_end_16(void) | |
566 | { | |
567 | __asm__ __volatile__ ( | |
568 | "mov r4, lr \n\t" | |
569 | "bl kprobes_test_case_end \n\t" | |
570 | "cmp r0, #0 \n\t" | |
571 | "bxne r0 \n\t" | |
572 | "mov r0, r4 \n\t" | |
573 | "add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" | |
574 | "ldmia sp!, {r4-r11} \n\t" | |
575 | "bx r0 \n\t" | |
576 | ); | |
577 | } | |
578 | ||
579 | void __naked __kprobes_test_case_end_32(void) | |
580 | { | |
581 | __asm__ __volatile__ ( | |
582 | ".arm \n\t" | |
583 | "orr lr, lr, #1 @ will return to Thumb code \n\t" | |
584 | "ldr pc, 1f \n\t" | |
585 | "1: \n\t" | |
586 | ".word __kprobes_test_case_end_16 \n\t" | |
587 | ); | |
588 | } | |
589 | ||
590 | #endif | |
591 | ||
592 | ||
593 | int kprobe_test_flags; | |
594 | int kprobe_test_cc_position; | |
595 | ||
596 | static int test_try_count; | |
597 | static int test_pass_count; | |
598 | static int test_fail_count; | |
599 | ||
600 | static struct pt_regs initial_regs; | |
601 | static struct pt_regs expected_regs; | |
602 | static struct pt_regs result_regs; | |
603 | ||
604 | static u32 expected_memory[TEST_MEMORY_SIZE/sizeof(u32)]; | |
605 | ||
606 | static const char *current_title; | |
607 | static struct test_arg *current_args; | |
608 | static u32 *current_stack; | |
609 | static uintptr_t current_branch_target; | |
610 | ||
611 | static uintptr_t current_code_start; | |
612 | static kprobe_opcode_t current_instruction; | |
613 | ||
614 | ||
615 | #define TEST_CASE_PASSED -1 | |
616 | #define TEST_CASE_FAILED -2 | |
617 | ||
618 | static int test_case_run_count; | |
619 | static bool test_case_is_thumb; | |
620 | static int test_instance; | |
621 | ||
622 | /* | |
623 | * We ignore the state of the imprecise abort disable flag (CPSR.A) because this | |
624 | * can change randomly as the kernel doesn't take care to preserve or initialise | |
625 | * this across context switches. Also, with Security Extentions, the flag may | |
626 | * not be under control of the kernel; for this reason we ignore the state of | |
627 | * the FIQ disable flag CPSR.F as well. | |
628 | */ | |
629 | #define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT) | |
630 | ||
631 | static unsigned long test_check_cc(int cc, unsigned long cpsr) | |
632 | { | |
633 | unsigned long temp; | |
634 | ||
635 | switch (cc) { | |
636 | case 0x0: /* eq */ | |
637 | return cpsr & PSR_Z_BIT; | |
638 | ||
639 | case 0x1: /* ne */ | |
640 | return (~cpsr) & PSR_Z_BIT; | |
641 | ||
642 | case 0x2: /* cs */ | |
643 | return cpsr & PSR_C_BIT; | |
644 | ||
645 | case 0x3: /* cc */ | |
646 | return (~cpsr) & PSR_C_BIT; | |
647 | ||
648 | case 0x4: /* mi */ | |
649 | return cpsr & PSR_N_BIT; | |
650 | ||
651 | case 0x5: /* pl */ | |
652 | return (~cpsr) & PSR_N_BIT; | |
653 | ||
654 | case 0x6: /* vs */ | |
655 | return cpsr & PSR_V_BIT; | |
656 | ||
657 | case 0x7: /* vc */ | |
658 | return (~cpsr) & PSR_V_BIT; | |
659 | ||
660 | case 0x8: /* hi */ | |
661 | cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | |
662 | return cpsr & PSR_C_BIT; | |
663 | ||
664 | case 0x9: /* ls */ | |
665 | cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | |
666 | return (~cpsr) & PSR_C_BIT; | |
667 | ||
668 | case 0xa: /* ge */ | |
669 | cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | |
670 | return (~cpsr) & PSR_N_BIT; | |
671 | ||
672 | case 0xb: /* lt */ | |
673 | cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | |
674 | return cpsr & PSR_N_BIT; | |
675 | ||
676 | case 0xc: /* gt */ | |
677 | temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | |
678 | temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ | |
679 | return (~temp) & PSR_N_BIT; | |
680 | ||
681 | case 0xd: /* le */ | |
682 | temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | |
683 | temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ | |
684 | return temp & PSR_N_BIT; | |
685 | ||
686 | case 0xe: /* al */ | |
687 | case 0xf: /* unconditional */ | |
688 | return true; | |
689 | } | |
690 | BUG(); | |
691 | return false; | |
692 | } | |
693 | ||
694 | static int is_last_scenario; | |
695 | static int probe_should_run; /* 0 = no, 1 = yes, -1 = unknown */ | |
696 | static int memory_needs_checking; | |
697 | ||
698 | static unsigned long test_context_cpsr(int scenario) | |
699 | { | |
700 | unsigned long cpsr; | |
701 | ||
702 | probe_should_run = 1; | |
703 | ||
704 | /* Default case is that we cycle through 16 combinations of flags */ | |
705 | cpsr = (scenario & 0xf) << 28; /* N,Z,C,V flags */ | |
706 | cpsr |= (scenario & 0xf) << 16; /* GE flags */ | |
707 | cpsr |= (scenario & 0x1) << 27; /* Toggle Q flag */ | |
708 | ||
709 | if (!test_case_is_thumb) { | |
710 | /* Testing ARM code */ | |
711 | probe_should_run = test_check_cc(current_instruction >> 28, cpsr) != 0; | |
712 | if (scenario == 15) | |
713 | is_last_scenario = true; | |
714 | ||
715 | } else if (kprobe_test_flags & TEST_FLAG_NO_ITBLOCK) { | |
716 | /* Testing Thumb code without setting ITSTATE */ | |
717 | if (kprobe_test_cc_position) { | |
718 | int cc = (current_instruction >> kprobe_test_cc_position) & 0xf; | |
719 | probe_should_run = test_check_cc(cc, cpsr) != 0; | |
720 | } | |
721 | ||
722 | if (scenario == 15) | |
723 | is_last_scenario = true; | |
724 | ||
725 | } else if (kprobe_test_flags & TEST_FLAG_FULL_ITBLOCK) { | |
726 | /* Testing Thumb code with all combinations of ITSTATE */ | |
727 | unsigned x = (scenario >> 4); | |
728 | unsigned cond_base = x % 7; /* ITSTATE<7:5> */ | |
729 | unsigned mask = x / 7 + 2; /* ITSTATE<4:0>, bits reversed */ | |
730 | ||
731 | if (mask > 0x1f) { | |
732 | /* Finish by testing state from instruction 'itt al' */ | |
733 | cond_base = 7; | |
734 | mask = 0x4; | |
735 | if ((scenario & 0xf) == 0xf) | |
736 | is_last_scenario = true; | |
737 | } | |
738 | ||
739 | cpsr |= cond_base << 13; /* ITSTATE<7:5> */ | |
740 | cpsr |= (mask & 0x1) << 12; /* ITSTATE<4> */ | |
741 | cpsr |= (mask & 0x2) << 10; /* ITSTATE<3> */ | |
742 | cpsr |= (mask & 0x4) << 8; /* ITSTATE<2> */ | |
743 | cpsr |= (mask & 0x8) << 23; /* ITSTATE<1> */ | |
744 | cpsr |= (mask & 0x10) << 21; /* ITSTATE<0> */ | |
745 | ||
746 | probe_should_run = test_check_cc((cpsr >> 12) & 0xf, cpsr) != 0; | |
747 | ||
748 | } else { | |
749 | /* Testing Thumb code with several combinations of ITSTATE */ | |
750 | switch (scenario) { | |
751 | case 16: /* Clear NZCV flags and 'it eq' state (false as Z=0) */ | |
752 | cpsr = 0x00000800; | |
753 | probe_should_run = 0; | |
754 | break; | |
755 | case 17: /* Set NZCV flags and 'it vc' state (false as V=1) */ | |
756 | cpsr = 0xf0007800; | |
757 | probe_should_run = 0; | |
758 | break; | |
759 | case 18: /* Clear NZCV flags and 'it ls' state (true as C=0) */ | |
760 | cpsr = 0x00009800; | |
761 | break; | |
762 | case 19: /* Set NZCV flags and 'it cs' state (true as C=1) */ | |
763 | cpsr = 0xf0002800; | |
764 | is_last_scenario = true; | |
765 | break; | |
766 | } | |
767 | } | |
768 | ||
769 | return cpsr; | |
770 | } | |
771 | ||
772 | static void setup_test_context(struct pt_regs *regs) | |
773 | { | |
774 | int scenario = test_case_run_count>>1; | |
775 | unsigned long val; | |
776 | struct test_arg *args; | |
777 | int i; | |
778 | ||
779 | is_last_scenario = false; | |
780 | memory_needs_checking = false; | |
781 | ||
782 | /* Initialise test memory on stack */ | |
783 | val = (scenario & 1) ? VALM : ~VALM; | |
784 | for (i = 0; i < TEST_MEMORY_SIZE / sizeof(current_stack[0]); ++i) | |
785 | current_stack[i] = val + (i << 8); | |
786 | /* Put target of branch on stack for tests which load PC from memory */ | |
787 | if (current_branch_target) | |
788 | current_stack[15] = current_branch_target; | |
789 | /* Put a value for SP on stack for tests which load SP from memory */ | |
790 | current_stack[13] = (u32)current_stack + 120; | |
791 | ||
792 | /* Initialise register values to their default state */ | |
793 | val = (scenario & 2) ? VALR : ~VALR; | |
794 | for (i = 0; i < 13; ++i) | |
795 | regs->uregs[i] = val ^ (i << 8); | |
796 | regs->ARM_lr = val ^ (14 << 8); | |
797 | regs->ARM_cpsr &= ~(APSR_MASK | PSR_IT_MASK); | |
798 | regs->ARM_cpsr |= test_context_cpsr(scenario); | |
799 | ||
800 | /* Perform testcase specific register setup */ | |
801 | args = current_args; | |
802 | for (; args[0].type != ARG_TYPE_END; ++args) | |
803 | switch (args[0].type) { | |
804 | case ARG_TYPE_REG: { | |
805 | struct test_arg_regptr *arg = | |
806 | (struct test_arg_regptr *)args; | |
807 | regs->uregs[arg->reg] = arg->val; | |
808 | break; | |
809 | } | |
810 | case ARG_TYPE_PTR: { | |
811 | struct test_arg_regptr *arg = | |
812 | (struct test_arg_regptr *)args; | |
813 | regs->uregs[arg->reg] = | |
814 | (unsigned long)current_stack + arg->val; | |
815 | memory_needs_checking = true; | |
816 | break; | |
817 | } | |
818 | case ARG_TYPE_MEM: { | |
819 | struct test_arg_mem *arg = (struct test_arg_mem *)args; | |
820 | current_stack[arg->index] = arg->val; | |
821 | break; | |
822 | } | |
823 | default: | |
824 | break; | |
825 | } | |
826 | } | |
827 | ||
828 | struct test_probe { | |
829 | struct kprobe kprobe; | |
830 | bool registered; | |
831 | int hit; | |
832 | }; | |
833 | ||
834 | static void unregister_test_probe(struct test_probe *probe) | |
835 | { | |
836 | if (probe->registered) { | |
837 | unregister_kprobe(&probe->kprobe); | |
838 | probe->kprobe.flags = 0; /* Clear disable flag to allow reuse */ | |
839 | } | |
840 | probe->registered = false; | |
841 | } | |
842 | ||
843 | static int register_test_probe(struct test_probe *probe) | |
844 | { | |
845 | int ret; | |
846 | ||
847 | if (probe->registered) | |
848 | BUG(); | |
849 | ||
850 | ret = register_kprobe(&probe->kprobe); | |
851 | if (ret >= 0) { | |
852 | probe->registered = true; | |
853 | probe->hit = -1; | |
854 | } | |
855 | return ret; | |
856 | } | |
857 | ||
858 | static int __kprobes | |
859 | test_before_pre_handler(struct kprobe *p, struct pt_regs *regs) | |
860 | { | |
861 | container_of(p, struct test_probe, kprobe)->hit = test_instance; | |
862 | return 0; | |
863 | } | |
864 | ||
865 | static void __kprobes | |
866 | test_before_post_handler(struct kprobe *p, struct pt_regs *regs, | |
867 | unsigned long flags) | |
868 | { | |
869 | setup_test_context(regs); | |
870 | initial_regs = *regs; | |
871 | initial_regs.ARM_cpsr &= ~PSR_IGNORE_BITS; | |
872 | } | |
873 | ||
874 | static int __kprobes | |
875 | test_case_pre_handler(struct kprobe *p, struct pt_regs *regs) | |
876 | { | |
877 | container_of(p, struct test_probe, kprobe)->hit = test_instance; | |
878 | return 0; | |
879 | } | |
880 | ||
881 | static int __kprobes | |
882 | test_after_pre_handler(struct kprobe *p, struct pt_regs *regs) | |
883 | { | |
884 | if (container_of(p, struct test_probe, kprobe)->hit == test_instance) | |
885 | return 0; /* Already run for this test instance */ | |
886 | ||
887 | result_regs = *regs; | |
888 | result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS; | |
889 | ||
890 | /* Undo any changes done to SP by the test case */ | |
891 | regs->ARM_sp = (unsigned long)current_stack; | |
892 | ||
893 | container_of(p, struct test_probe, kprobe)->hit = test_instance; | |
894 | return 0; | |
895 | } | |
896 | ||
897 | static struct test_probe test_before_probe = { | |
898 | .kprobe.pre_handler = test_before_pre_handler, | |
899 | .kprobe.post_handler = test_before_post_handler, | |
900 | }; | |
901 | ||
902 | static struct test_probe test_case_probe = { | |
903 | .kprobe.pre_handler = test_case_pre_handler, | |
904 | }; | |
905 | ||
906 | static struct test_probe test_after_probe = { | |
907 | .kprobe.pre_handler = test_after_pre_handler, | |
908 | }; | |
909 | ||
910 | static struct test_probe test_after2_probe = { | |
911 | .kprobe.pre_handler = test_after_pre_handler, | |
912 | }; | |
913 | ||
914 | static void test_case_cleanup(void) | |
915 | { | |
916 | unregister_test_probe(&test_before_probe); | |
917 | unregister_test_probe(&test_case_probe); | |
918 | unregister_test_probe(&test_after_probe); | |
919 | unregister_test_probe(&test_after2_probe); | |
920 | } | |
921 | ||
922 | static void print_registers(struct pt_regs *regs) | |
923 | { | |
924 | pr_err("r0 %08lx | r1 %08lx | r2 %08lx | r3 %08lx\n", | |
925 | regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); | |
926 | pr_err("r4 %08lx | r5 %08lx | r6 %08lx | r7 %08lx\n", | |
927 | regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7); | |
928 | pr_err("r8 %08lx | r9 %08lx | r10 %08lx | r11 %08lx\n", | |
929 | regs->ARM_r8, regs->ARM_r9, regs->ARM_r10, regs->ARM_fp); | |
930 | pr_err("r12 %08lx | sp %08lx | lr %08lx | pc %08lx\n", | |
931 | regs->ARM_ip, regs->ARM_sp, regs->ARM_lr, regs->ARM_pc); | |
932 | pr_err("cpsr %08lx\n", regs->ARM_cpsr); | |
933 | } | |
934 | ||
935 | static void print_memory(u32 *mem, size_t size) | |
936 | { | |
937 | int i; | |
938 | for (i = 0; i < size / sizeof(u32); i += 4) | |
939 | pr_err("%08x %08x %08x %08x\n", mem[i], mem[i+1], | |
940 | mem[i+2], mem[i+3]); | |
941 | } | |
942 | ||
943 | static size_t expected_memory_size(u32 *sp) | |
944 | { | |
945 | size_t size = sizeof(expected_memory); | |
946 | int offset = (uintptr_t)sp - (uintptr_t)current_stack; | |
947 | if (offset > 0) | |
948 | size -= offset; | |
949 | return size; | |
950 | } | |
951 | ||
952 | static void test_case_failed(const char *message) | |
953 | { | |
954 | test_case_cleanup(); | |
955 | ||
956 | pr_err("FAIL: %s\n", message); | |
957 | pr_err("FAIL: Test %s\n", current_title); | |
958 | pr_err("FAIL: Scenario %d\n", test_case_run_count >> 1); | |
959 | } | |
960 | ||
961 | static unsigned long next_instruction(unsigned long pc) | |
962 | { | |
963 | #ifdef CONFIG_THUMB2_KERNEL | |
964 | if ((pc & 1) && !is_wide_instruction(*(u16 *)(pc - 1))) | |
965 | return pc + 2; | |
966 | else | |
967 | #endif | |
968 | return pc + 4; | |
969 | } | |
970 | ||
971 | static uintptr_t __used kprobes_test_case_start(const char *title, void *stack) | |
972 | { | |
973 | struct test_arg *args; | |
974 | struct test_arg_end *end_arg; | |
975 | unsigned long test_code; | |
976 | ||
977 | args = (struct test_arg *)PTR_ALIGN(title + strlen(title) + 1, 4); | |
978 | ||
979 | current_title = title; | |
980 | current_args = args; | |
981 | current_stack = stack; | |
982 | ||
983 | ++test_try_count; | |
984 | ||
985 | while (args->type != ARG_TYPE_END) | |
986 | ++args; | |
987 | end_arg = (struct test_arg_end *)args; | |
988 | ||
989 | test_code = (unsigned long)(args + 1); /* Code starts after args */ | |
990 | ||
991 | test_case_is_thumb = end_arg->flags & ARG_FLAG_THUMB; | |
992 | if (test_case_is_thumb) | |
993 | test_code |= 1; | |
994 | ||
995 | current_code_start = test_code; | |
996 | ||
997 | current_branch_target = 0; | |
998 | if (end_arg->branch_offset != end_arg->end_offset) | |
999 | current_branch_target = test_code + end_arg->branch_offset; | |
1000 | ||
1001 | test_code += end_arg->code_offset; | |
1002 | test_before_probe.kprobe.addr = (kprobe_opcode_t *)test_code; | |
1003 | ||
1004 | test_code = next_instruction(test_code); | |
1005 | test_case_probe.kprobe.addr = (kprobe_opcode_t *)test_code; | |
1006 | ||
1007 | if (test_case_is_thumb) { | |
1008 | u16 *p = (u16 *)(test_code & ~1); | |
1009 | current_instruction = p[0]; | |
1010 | if (is_wide_instruction(current_instruction)) { | |
1011 | current_instruction <<= 16; | |
1012 | current_instruction |= p[1]; | |
1013 | } | |
1014 | } else { | |
1015 | current_instruction = *(u32 *)test_code; | |
1016 | } | |
1017 | ||
1018 | if (current_title[0] == '.') | |
1019 | verbose("%s\n", current_title); | |
1020 | else | |
1021 | verbose("%s\t@ %0*x\n", current_title, | |
1022 | test_case_is_thumb ? 4 : 8, | |
1023 | current_instruction); | |
1024 | ||
1025 | test_code = next_instruction(test_code); | |
1026 | test_after_probe.kprobe.addr = (kprobe_opcode_t *)test_code; | |
1027 | ||
1028 | if (kprobe_test_flags & TEST_FLAG_NARROW_INSTR) { | |
1029 | if (!test_case_is_thumb || | |
1030 | is_wide_instruction(current_instruction)) { | |
1031 | test_case_failed("expected 16-bit instruction"); | |
1032 | goto fail; | |
1033 | } | |
1034 | } else { | |
1035 | if (test_case_is_thumb && | |
1036 | !is_wide_instruction(current_instruction)) { | |
1037 | test_case_failed("expected 32-bit instruction"); | |
1038 | goto fail; | |
1039 | } | |
1040 | } | |
1041 | ||
1042 | if (end_arg->flags & ARG_FLAG_UNSUPPORTED) { | |
1043 | if (register_test_probe(&test_case_probe) < 0) | |
1044 | goto pass; | |
1045 | test_case_failed("registered probe for unsupported instruction"); | |
1046 | goto fail; | |
1047 | } | |
1048 | ||
1049 | if (end_arg->flags & ARG_FLAG_SUPPORTED) { | |
1050 | if (register_test_probe(&test_case_probe) >= 0) | |
1051 | goto pass; | |
1052 | test_case_failed("couldn't register probe for supported instruction"); | |
1053 | goto fail; | |
1054 | } | |
1055 | ||
1056 | if (register_test_probe(&test_before_probe) < 0) { | |
1057 | test_case_failed("register test_before_probe failed"); | |
1058 | goto fail; | |
1059 | } | |
1060 | if (register_test_probe(&test_after_probe) < 0) { | |
1061 | test_case_failed("register test_after_probe failed"); | |
1062 | goto fail; | |
1063 | } | |
1064 | if (current_branch_target) { | |
1065 | test_after2_probe.kprobe.addr = | |
1066 | (kprobe_opcode_t *)current_branch_target; | |
1067 | if (register_test_probe(&test_after2_probe) < 0) { | |
1068 | test_case_failed("register test_after2_probe failed"); | |
1069 | goto fail; | |
1070 | } | |
1071 | } | |
1072 | ||
1073 | /* Start first run of test case */ | |
1074 | test_case_run_count = 0; | |
1075 | ++test_instance; | |
1076 | return current_code_start; | |
1077 | pass: | |
1078 | test_case_run_count = TEST_CASE_PASSED; | |
1079 | return (uintptr_t)test_after_probe.kprobe.addr; | |
1080 | fail: | |
1081 | test_case_run_count = TEST_CASE_FAILED; | |
1082 | return (uintptr_t)test_after_probe.kprobe.addr; | |
1083 | } | |
1084 | ||
1085 | static bool check_test_results(void) | |
1086 | { | |
1087 | size_t mem_size = 0; | |
1088 | u32 *mem = 0; | |
1089 | ||
1090 | if (memcmp(&expected_regs, &result_regs, sizeof(expected_regs))) { | |
1091 | test_case_failed("registers differ"); | |
1092 | goto fail; | |
1093 | } | |
1094 | ||
1095 | if (memory_needs_checking) { | |
1096 | mem = (u32 *)result_regs.ARM_sp; | |
1097 | mem_size = expected_memory_size(mem); | |
1098 | if (memcmp(expected_memory, mem, mem_size)) { | |
1099 | test_case_failed("test memory differs"); | |
1100 | goto fail; | |
1101 | } | |
1102 | } | |
1103 | ||
1104 | return true; | |
1105 | ||
1106 | fail: | |
1107 | pr_err("initial_regs:\n"); | |
1108 | print_registers(&initial_regs); | |
1109 | pr_err("expected_regs:\n"); | |
1110 | print_registers(&expected_regs); | |
1111 | pr_err("result_regs:\n"); | |
1112 | print_registers(&result_regs); | |
1113 | ||
1114 | if (mem) { | |
1115 | pr_err("current_stack=%p\n", current_stack); | |
1116 | pr_err("expected_memory:\n"); | |
1117 | print_memory(expected_memory, mem_size); | |
1118 | pr_err("result_memory:\n"); | |
1119 | print_memory(mem, mem_size); | |
1120 | } | |
1121 | ||
1122 | return false; | |
1123 | } | |
1124 | ||
1125 | static uintptr_t __used kprobes_test_case_end(void) | |
1126 | { | |
1127 | if (test_case_run_count < 0) { | |
1128 | if (test_case_run_count == TEST_CASE_PASSED) | |
1129 | /* kprobes_test_case_start did all the needed testing */ | |
1130 | goto pass; | |
1131 | else | |
1132 | /* kprobes_test_case_start failed */ | |
1133 | goto fail; | |
1134 | } | |
1135 | ||
1136 | if (test_before_probe.hit != test_instance) { | |
1137 | test_case_failed("test_before_handler not run"); | |
1138 | goto fail; | |
1139 | } | |
1140 | ||
1141 | if (test_after_probe.hit != test_instance && | |
1142 | test_after2_probe.hit != test_instance) { | |
1143 | test_case_failed("test_after_handler not run"); | |
1144 | goto fail; | |
1145 | } | |
1146 | ||
1147 | /* | |
1148 | * Even numbered test runs ran without a probe on the test case so | |
1149 | * we can gather reference results. The subsequent odd numbered run | |
1150 | * will have the probe inserted. | |
1151 | */ | |
1152 | if ((test_case_run_count & 1) == 0) { | |
1153 | /* Save results from run without probe */ | |
1154 | u32 *mem = (u32 *)result_regs.ARM_sp; | |
1155 | expected_regs = result_regs; | |
1156 | memcpy(expected_memory, mem, expected_memory_size(mem)); | |
1157 | ||
1158 | /* Insert probe onto test case instruction */ | |
1159 | if (register_test_probe(&test_case_probe) < 0) { | |
1160 | test_case_failed("register test_case_probe failed"); | |
1161 | goto fail; | |
1162 | } | |
1163 | } else { | |
1164 | /* Check probe ran as expected */ | |
1165 | if (probe_should_run == 1) { | |
1166 | if (test_case_probe.hit != test_instance) { | |
1167 | test_case_failed("test_case_handler not run"); | |
1168 | goto fail; | |
1169 | } | |
1170 | } else if (probe_should_run == 0) { | |
1171 | if (test_case_probe.hit == test_instance) { | |
1172 | test_case_failed("test_case_handler ran"); | |
1173 | goto fail; | |
1174 | } | |
1175 | } | |
1176 | ||
1177 | /* Remove probe for any subsequent reference run */ | |
1178 | unregister_test_probe(&test_case_probe); | |
1179 | ||
1180 | if (!check_test_results()) | |
1181 | goto fail; | |
1182 | ||
1183 | if (is_last_scenario) | |
1184 | goto pass; | |
1185 | } | |
1186 | ||
1187 | /* Do next test run */ | |
1188 | ++test_case_run_count; | |
1189 | ++test_instance; | |
1190 | return current_code_start; | |
1191 | fail: | |
1192 | ++test_fail_count; | |
1193 | goto end; | |
1194 | pass: | |
1195 | ++test_pass_count; | |
1196 | end: | |
1197 | test_case_cleanup(); | |
1198 | return 0; | |
1199 | } | |
1200 | ||
1201 | ||
9eed1797 JM |
1202 | /* |
1203 | * Top level test functions | |
1204 | */ | |
1205 | ||
68f360e7 | 1206 | static int run_test_cases(void (*tests)(void), const union decode_item *table) |
c7054aad | 1207 | { |
68f360e7 JM |
1208 | int ret; |
1209 | ||
1210 | pr_info(" Check decoding tables\n"); | |
1211 | ret = table_test(table); | |
1212 | if (ret) | |
1213 | return ret; | |
1214 | ||
c7054aad JM |
1215 | pr_info(" Run test cases\n"); |
1216 | tests(); | |
1217 | ||
1218 | return 0; | |
1219 | } | |
1220 | ||
1221 | ||
9eed1797 JM |
1222 | static int __init run_all_tests(void) |
1223 | { | |
1224 | int ret = 0; | |
1225 | ||
1226 | pr_info("Begining kprobe tests...\n"); | |
1227 | ||
1228 | #ifndef CONFIG_THUMB2_KERNEL | |
1229 | ||
1230 | pr_info("Probe ARM code\n"); | |
1231 | ret = run_api_tests(arm_func); | |
1232 | if (ret) | |
1233 | goto out; | |
1234 | ||
c0cc6df1 | 1235 | pr_info("ARM instruction simulation\n"); |
68f360e7 | 1236 | ret = run_test_cases(kprobe_arm_test_cases, kprobe_decode_arm_table); |
c0cc6df1 JM |
1237 | if (ret) |
1238 | goto out; | |
1239 | ||
9eed1797 JM |
1240 | #else /* CONFIG_THUMB2_KERNEL */ |
1241 | ||
1242 | pr_info("Probe 16-bit Thumb code\n"); | |
1243 | ret = run_api_tests(thumb16_func); | |
1244 | if (ret) | |
1245 | goto out; | |
1246 | ||
1247 | pr_info("Probe 32-bit Thumb code, even halfword\n"); | |
1248 | ret = run_api_tests(thumb32even_func); | |
1249 | if (ret) | |
1250 | goto out; | |
1251 | ||
1252 | pr_info("Probe 32-bit Thumb code, odd halfword\n"); | |
1253 | ret = run_api_tests(thumb32odd_func); | |
1254 | if (ret) | |
1255 | goto out; | |
1256 | ||
c7054aad | 1257 | pr_info("16-bit Thumb instruction simulation\n"); |
68f360e7 JM |
1258 | ret = run_test_cases(kprobe_thumb16_test_cases, |
1259 | kprobe_decode_thumb16_table); | |
c7054aad JM |
1260 | if (ret) |
1261 | goto out; | |
1262 | ||
1263 | pr_info("32-bit Thumb instruction simulation\n"); | |
68f360e7 JM |
1264 | ret = run_test_cases(kprobe_thumb32_test_cases, |
1265 | kprobe_decode_thumb32_table); | |
c7054aad JM |
1266 | if (ret) |
1267 | goto out; | |
9eed1797 JM |
1268 | #endif |
1269 | ||
c7054aad JM |
1270 | pr_info("Total instruction simulation tests=%d, pass=%d fail=%d\n", |
1271 | test_try_count, test_pass_count, test_fail_count); | |
1272 | if (test_fail_count) { | |
1273 | ret = -EINVAL; | |
1274 | goto out; | |
1275 | } | |
1276 | ||
9eed1797 JM |
1277 | out: |
1278 | if (ret == 0) | |
1279 | pr_info("Finished kprobe tests OK\n"); | |
1280 | else | |
1281 | pr_err("kprobe tests failed\n"); | |
1282 | ||
1283 | return ret; | |
1284 | } | |
1285 | ||
1286 | ||
1287 | /* | |
1288 | * Module setup | |
1289 | */ | |
1290 | ||
1291 | #ifdef MODULE | |
1292 | ||
1293 | static void __exit kprobe_test_exit(void) | |
1294 | { | |
1295 | } | |
1296 | ||
1297 | module_init(run_all_tests) | |
1298 | module_exit(kprobe_test_exit) | |
1299 | MODULE_LICENSE("GPL"); | |
1300 | ||
1301 | #else /* !MODULE */ | |
1302 | ||
1303 | late_initcall(run_all_tests); | |
1304 | ||
1305 | #endif |