Lines Matching +full:even +full:- +full:numbered

1 // SPDX-License-Identifier: GPL-2.0-only
3 * arch/arm/kernel/kprobes-test.c
12 * supported instruction sets: ARM, 16-bit Thumb, and 32-bit Thumb. These tests
23 * The individual test cases are in kprobes-test-arm.c and kprobes-test-thumb.c
24 * which use the macros defined in kprobes-test.h. The rest of this
31 * -------------------
41 * post-handler of the test_before probe is used to modify the saved CPU
43 * pre-handler of the of the test_after probe saves a copy of the CPU
83 * (branch backwards). In these, the local variables numbered 1, 50, 2 and
87 * ---------
127 * .short 50f-0f @ offset of 'test_before'
128 * .short 2f-0f @ offset of 'test_after2' (if relevent)
129 * .short 99f-0f @ offset of 'test_done'
161 * pre-handler for this (test_after_pre_handler) will save a copy of the
170 * by one. For even runs, kprobes_test_case_end() saves a copy of the
173 * value to cause the test case code to be re-run.
175 * For odd numbered runs, kprobes_test_case_end() compares the register and
176 * stack buffer contents to those that were saved on the previous even
177 * numbered run (the one without the kprobe on test_insn). These should be
185 * -------------------
211 #include "test-core.h"
212 #include "../decode-arm.h"
213 #include "../decode-thumb.h"
313 if (regs->ARM_r0 == FUNC_ARG1 && regs->ARM_r1 == FUNC_ARG2) in pre_handler()
322 if (regs->ARM_r0 != FUNC_ARG1 + FUNC_ARG2 || regs->ARM_r1 != FUNC_ARG2) in post_handler()
349 return -EINVAL; in test_kprobe()
352 return -EINVAL; in test_kprobe()
356 return -EINVAL; in test_kprobe()
359 return -EINVAL; in test_kprobe()
363 return -EINVAL; in test_kprobe()
399 return -EINVAL; in test_kretprobe()
402 return -EINVAL; in test_kretprobe()
405 return -EINVAL; in test_kretprobe()
408 return -EINVAL; in test_kretprobe()
455 "stmdb"wide" sp!, {r3-r11,lr} \n\t" in benchmark_pushpop1()
456 "ldmia"wide" sp!, {r3-r11,pc}" in benchmark_pushpop1()
463 "stmdb"wide" sp!, {r0-r8,lr} \n\t" in benchmark_pushpop2()
464 "ldmia"wide" sp!, {r0-r8,pc}" in benchmark_pushpop2()
490 "push.n {r0-r7,lr} \n\t" in benchmark_pushpop_thumb()
491 "pop.n {r0-r7,pc}" in benchmark_pushpop_thumb()
509 for (i = n; i > 0; --i) in benchmark()
511 t = sched_clock() - t0; in benchmark()
553 {&benchmark_pushpop1, 0, "stmdb sp!, {r3-r11,lr}"}, in run_benchmarks()
554 {&benchmark_pushpop1, 4, "ldmia sp!, {r3-r11,pc}"}, in run_benchmarks()
555 {&benchmark_pushpop2, 0, "stmdb sp!, {r0-r8,lr}"}, in run_benchmarks()
556 {&benchmark_pushpop2, 4, "ldmia sp!, {r0-r8,pc}"}, in run_benchmarks()
562 {&benchmark_pushpop_thumb, 0, "push.n {r0-r7,lr}"}, in run_benchmarks()
563 {&benchmark_pushpop_thumb, 2, "pop.n {r0-r7,pc}"}, in run_benchmarks()
569 for (b = list; b->fn; ++b) { in run_benchmarks()
570 ret = kprobe_benchmark(b->fn, b->offset); in run_benchmarks()
573 pr_info(" %dns for kprobe %s\n", ret, b->title); in run_benchmarks()
584 * Decoding table self-consistency tests
604 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; in table_iter()
623 message, h->mask.bits, h->value.bits); in table_test_fail()
624 return -EINVAL; in table_test_fail()
636 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; in table_test_fn()
638 if (h->value.bits & ~h->mask.bits) in table_test_fn()
641 if ((h->mask.bits & a->parent_mask) != a->parent_mask) in table_test_fn()
644 if ((h->value.bits ^ a->parent_value) & a->parent_mask) in table_test_fn()
650 args2.parent_mask = h->mask.bits; in table_test_fn()
651 args2.parent_value = h->value.bits; in table_test_fn()
652 return table_iter(d->table.table, table_test_fn, &args2); in table_test_fn()
728 int r = (h->type_regs.bits >> (DECODE_TYPE_BITS + i)) & 0xf; in coverage_start_registers()
737 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; in coverage_start_fn()
738 struct coverage_entry *entry = coverage->base + coverage->num_entries; in coverage_start_fn()
740 if (coverage->num_entries == MAX_COVERAGE_ENTRIES - 1) { in coverage_start_fn()
742 return -ENOMEM; in coverage_start_fn()
745 ++coverage->num_entries; in coverage_start_fn()
747 entry->header = h; in coverage_start_fn()
748 entry->regs = coverage_start_registers(h); in coverage_start_fn()
749 entry->nesting = coverage->nesting; in coverage_start_fn()
750 entry->matched = false; in coverage_start_fn()
755 ++coverage->nesting; in coverage_start_fn()
756 ret = table_iter(d->table.table, coverage_start_fn, coverage); in coverage_start_fn()
757 --coverage->nesting; in coverage_start_fn()
777 int regs = entry->header->type_regs.bits >> DECODE_TYPE_BITS; in coverage_add_registers()
793 entry->regs &= ~(flag << i); in coverage_add_registers()
827 entry->regs &= ~(COVERAGE_PCWB << i); in coverage_add_registers()
850 const struct decode_header *h = entry->header; in coverage_add()
851 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; in coverage_add()
853 if (entry->nesting > nesting) in coverage_add()
854 continue; /* Skip sub-table we didn't match */ in coverage_add()
856 if (entry->nesting < nesting) in coverage_add()
857 break; /* End of sub-table we were scanning */ in coverage_add()
860 if ((insn & h->mask.bits) != h->value.bits) in coverage_add()
862 entry->matched = true; in coverage_add()
895 u32 mask = entry->header->mask.bits; in coverage_end()
896 u32 value = entry->header->value.bits; in coverage_end()
898 if (entry->regs) { in coverage_end()
900 mask, value, entry->regs); in coverage_end()
903 if (!entry->matched) { in coverage_end()
924 "stmdb sp!, {r2-r11} \n\t" in __kprobes_test_case_start()
944 "ldmia sp!, {r2-r11} \n\t" in __kprobes_test_case_end_32()
961 "ldmia sp!, {r2-r11} \n\t" in __kprobes_test_case_end_16()
1003 #define TEST_CASE_PASSED -1
1004 #define TEST_CASE_FAILED -2
1018 static int probe_should_run; /* 0 = no, 1 = yes, -1 = unknown */
1120 regs->uregs[i] = val ^ (i << 8); in setup_test_context()
1121 regs->ARM_lr = val ^ (14 << 8); in setup_test_context()
1122 regs->ARM_cpsr &= ~(APSR_MASK | PSR_IT_MASK); in setup_test_context()
1123 regs->ARM_cpsr |= test_context_cpsr(scenario); in setup_test_context()
1132 regs->uregs[arg->reg] = arg->val; in setup_test_context()
1138 regs->uregs[arg->reg] = in setup_test_context()
1139 (unsigned long)current_stack + arg->val; in setup_test_context()
1146 if (arg->reg == 13) in setup_test_context()
1147 regs->ARM_cpsr |= PSR_I_BIT; in setup_test_context()
1152 current_stack[arg->index] = arg->val; in setup_test_context()
1168 if (probe->registered) { in unregister_test_probe()
1169 unregister_kprobe(&probe->kprobe); in unregister_test_probe()
1170 probe->kprobe.flags = 0; /* Clear disable flag to allow reuse */ in unregister_test_probe()
1172 probe->registered = false; in unregister_test_probe()
1179 if (probe->registered) in register_test_probe()
1182 ret = register_kprobe(&probe->kprobe); in register_test_probe()
1184 probe->registered = true; in register_test_probe()
1185 probe->hit = -1; in register_test_probe()
1193 container_of(p, struct test_probe, kprobe)->hit = test_instance; in test_before_pre_handler()
1209 container_of(p, struct test_probe, kprobe)->hit = test_instance; in test_case_pre_handler()
1218 if (container_of(p, struct test_probe, kprobe)->hit == test_instance) in test_after_pre_handler()
1229 result_regs.uregs[arg->reg] &= arg->val; in test_after_pre_handler()
1233 regs->ARM_sp = (unsigned long)current_stack; in test_after_pre_handler()
1235 regs->ARM_cpsr &= ~PSR_I_BIT; in test_after_pre_handler()
1237 container_of(p, struct test_probe, kprobe)->hit = test_instance; in test_after_pre_handler()
1269 regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); in print_registers()
1271 regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7); in print_registers()
1273 regs->ARM_r8, regs->ARM_r9, regs->ARM_r10, regs->ARM_fp); in print_registers()
1275 regs->ARM_ip, regs->ARM_sp, regs->ARM_lr, regs->ARM_pc); in print_registers()
1276 pr_err("cpsr %08lx\n", regs->ARM_cpsr); in print_registers()
1290 int offset = (uintptr_t)sp - (uintptr_t)current_stack; in expected_memory_size()
1292 size -= offset; in expected_memory_size()
1309 !is_wide_instruction(__mem_to_opcode_thumb16(*(u16 *)(pc - 1)))) in next_instruction()
1329 while (args->type != ARG_TYPE_END) in kprobes_test_case_start()
1335 test_case_is_thumb = end_arg->flags & ARG_FLAG_THUMB; in kprobes_test_case_start()
1342 if (end_arg->branch_offset != end_arg->end_offset) in kprobes_test_case_start()
1343 current_branch_target = test_code + end_arg->branch_offset; in kprobes_test_case_start()
1345 test_code += end_arg->code_offset; in kprobes_test_case_start()
1375 test_case_failed("expected 16-bit instruction"); in kprobes_test_case_start()
1381 test_case_failed("expected 32-bit instruction"); in kprobes_test_case_start()
1388 if (end_arg->flags & ARG_FLAG_UNSUPPORTED) { in kprobes_test_case_start()
1395 if (end_arg->flags & ARG_FLAG_SUPPORTED) { in kprobes_test_case_start()
1493 * Even numbered test runs ran without a probe on the test case so in kprobes_test_case_end()
1494 * we can gather reference results. The subsequent odd numbered run in kprobes_test_case_end()
1592 pr_info("Probe 16-bit Thumb code\n"); in run_all_tests()
1597 pr_info("Probe 32-bit Thumb code, even halfword\n"); in run_all_tests()
1602 pr_info("Probe 32-bit Thumb code, odd halfword\n"); in run_all_tests()
1607 pr_info("16-bit Thumb instruction simulation\n"); in run_all_tests()
1613 pr_info("32-bit Thumb instruction simulation\n"); in run_all_tests()
1623 ret = -EINVAL; in run_all_tests()
1638 ret = -EINVAL; in run_all_tests()