162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <linux/kernel.h>
462306a36Sopenharmony_ci#include <linux/kprobes.h>
562306a36Sopenharmony_ci#include <linux/random.h>
662306a36Sopenharmony_ci#include <kunit/test.h>
762306a36Sopenharmony_ci#include "test_kprobes.h"
862306a36Sopenharmony_ci
962306a36Sopenharmony_cistatic struct kprobe kp;
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistatic void setup_kprobe(struct kunit *test, struct kprobe *kp,
1262306a36Sopenharmony_ci			 const char *symbol, int offset)
1362306a36Sopenharmony_ci{
1462306a36Sopenharmony_ci	kp->offset = offset;
1562306a36Sopenharmony_ci	kp->addr = NULL;
1662306a36Sopenharmony_ci	kp->symbol_name = symbol;
1762306a36Sopenharmony_ci}
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic void test_kprobe_offset(struct kunit *test, struct kprobe *kp,
2062306a36Sopenharmony_ci			       const char *target, int offset)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	int ret;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	setup_kprobe(test, kp, target, 0);
2562306a36Sopenharmony_ci	ret = register_kprobe(kp);
2662306a36Sopenharmony_ci	if (!ret)
2762306a36Sopenharmony_ci		unregister_kprobe(kp);
2862306a36Sopenharmony_ci	KUNIT_EXPECT_EQ(test, 0, ret);
2962306a36Sopenharmony_ci	setup_kprobe(test, kp, target, offset);
3062306a36Sopenharmony_ci	ret = register_kprobe(kp);
3162306a36Sopenharmony_ci	KUNIT_EXPECT_EQ(test, -EINVAL, ret);
3262306a36Sopenharmony_ci	if (!ret)
3362306a36Sopenharmony_ci		unregister_kprobe(kp);
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistatic void test_kprobe_odd(struct kunit *test)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	test_kprobe_offset(test, &kp, "kprobes_target_odd",
3962306a36Sopenharmony_ci			   kprobes_target_odd_offs);
4062306a36Sopenharmony_ci}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic void test_kprobe_in_insn4(struct kunit *test)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	test_kprobe_offset(test, &kp, "kprobes_target_in_insn4",
4562306a36Sopenharmony_ci			   kprobes_target_in_insn4_offs);
4662306a36Sopenharmony_ci}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistatic void test_kprobe_in_insn6_lo(struct kunit *test)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	test_kprobe_offset(test, &kp, "kprobes_target_in_insn6_lo",
5162306a36Sopenharmony_ci			   kprobes_target_in_insn6_lo_offs);
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic void test_kprobe_in_insn6_hi(struct kunit *test)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	test_kprobe_offset(test, &kp, "kprobes_target_in_insn6_hi",
5762306a36Sopenharmony_ci			   kprobes_target_in_insn6_hi_offs);
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic struct kunit_case kprobes_testcases[] = {
6162306a36Sopenharmony_ci	KUNIT_CASE(test_kprobe_odd),
6262306a36Sopenharmony_ci	KUNIT_CASE(test_kprobe_in_insn4),
6362306a36Sopenharmony_ci	KUNIT_CASE(test_kprobe_in_insn6_lo),
6462306a36Sopenharmony_ci	KUNIT_CASE(test_kprobe_in_insn6_hi),
6562306a36Sopenharmony_ci	{}
6662306a36Sopenharmony_ci};
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cistatic struct kunit_suite kprobes_test_suite = {
6962306a36Sopenharmony_ci	.name = "kprobes_test_s390",
7062306a36Sopenharmony_ci	.test_cases = kprobes_testcases,
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cikunit_test_suites(&kprobes_test_suite);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ciMODULE_LICENSE("GPL");
76