blob: e78f18144145937f8bbfb4d2b229a69ab9c4bf3c [file] [log] [blame]
Thomas Gleixner71700662019-05-19 15:51:55 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +01002/*
3 * test_kprobes.c - simple sanity test for *probes
4 *
5 * Copyright IBM Corp. 2008
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +01006 */
7
8#include <linux/kernel.h>
9#include <linux/kprobes.h>
10#include <linux/random.h>
Sven Schnellee44e81c2021-10-21 09:54:24 +090011#include <kunit/test.h>
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +010012
13#define div_factor 3
14
Masami Hiramatsu2c7d6622017-10-06 08:15:17 +090015static u32 rand1, preh_val, posth_val;
Masami Hiramatsu8e114402009-01-06 14:41:47 -080016static u32 (*target)(u32 value);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -080017static u32 (*target2)(u32 value);
Sven Schnellee44e81c2021-10-21 09:54:24 +090018static struct kunit *current_test;
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +010019
20static noinline u32 kprobe_target(u32 value)
21{
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +010022 return (value / div_factor);
23}
24
25static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
26{
Sven Schnellee44e81c2021-10-21 09:54:24 +090027 KUNIT_EXPECT_FALSE(current_test, preemptible());
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +010028 preh_val = (rand1 / div_factor);
29 return 0;
30}
31
32static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
33 unsigned long flags)
34{
Sven Schnellee44e81c2021-10-21 09:54:24 +090035 KUNIT_EXPECT_FALSE(current_test, preemptible());
36 KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor));
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +010037 posth_val = preh_val + div_factor;
38}
39
40static struct kprobe kp = {
41 .symbol_name = "kprobe_target",
42 .pre_handler = kp_pre_handler,
43 .post_handler = kp_post_handler
44};
45
Sven Schnellee44e81c2021-10-21 09:54:24 +090046static void test_kprobe(struct kunit *test)
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +010047{
Sven Schnellee44e81c2021-10-21 09:54:24 +090048 current_test = test;
49 KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp));
50 target(rand1);
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +010051 unregister_kprobe(&kp);
Sven Schnellee44e81c2021-10-21 09:54:24 +090052 KUNIT_EXPECT_NE(test, 0, preh_val);
53 KUNIT_EXPECT_NE(test, 0, posth_val);
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +010054}
55
Masami Hiramatsu12da3b82009-01-06 14:41:48 -080056static noinline u32 kprobe_target2(u32 value)
57{
58 return (value / div_factor) + 1;
59}
60
61static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
62{
63 preh_val = (rand1 / div_factor) + 1;
64 return 0;
65}
66
67static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
68 unsigned long flags)
69{
Sven Schnellee44e81c2021-10-21 09:54:24 +090070 KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor) + 1);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -080071 posth_val = preh_val + div_factor;
72}
73
74static struct kprobe kp2 = {
75 .symbol_name = "kprobe_target2",
76 .pre_handler = kp_pre_handler2,
77 .post_handler = kp_post_handler2
78};
79
Sven Schnellee44e81c2021-10-21 09:54:24 +090080static void test_kprobes(struct kunit *test)
Masami Hiramatsu12da3b82009-01-06 14:41:48 -080081{
Masami Hiramatsu12da3b82009-01-06 14:41:48 -080082 struct kprobe *kps[2] = {&kp, &kp2};
83
Sven Schnellee44e81c2021-10-21 09:54:24 +090084 current_test = test;
85
Masami Hiramatsufd02e6f2010-10-14 12:10:24 +090086 /* addr and flags should be cleard for reusing kprobe. */
87 kp.addr = NULL;
88 kp.flags = 0;
Sven Schnellee44e81c2021-10-21 09:54:24 +090089
90 KUNIT_EXPECT_EQ(test, 0, register_kprobes(kps, 2));
91 preh_val = 0;
92 posth_val = 0;
93 target(rand1);
94
95 KUNIT_EXPECT_NE(test, 0, preh_val);
96 KUNIT_EXPECT_NE(test, 0, posth_val);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -080097
98 preh_val = 0;
99 posth_val = 0;
Sven Schnellee44e81c2021-10-21 09:54:24 +0900100 target2(rand1);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800101
Sven Schnellee44e81c2021-10-21 09:54:24 +0900102 KUNIT_EXPECT_NE(test, 0, preh_val);
103 KUNIT_EXPECT_NE(test, 0, posth_val);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800104 unregister_kprobes(kps, 2);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800105}
106
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100107#ifdef CONFIG_KRETPROBES
108static u32 krph_val;
109
Abhishek Sagarf47cd9b2008-02-06 01:38:22 -0800110static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
111{
Sven Schnellee44e81c2021-10-21 09:54:24 +0900112 KUNIT_EXPECT_FALSE(current_test, preemptible());
Abhishek Sagarf47cd9b2008-02-06 01:38:22 -0800113 krph_val = (rand1 / div_factor);
114 return 0;
115}
116
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100117static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
118{
119 unsigned long ret = regs_return_value(regs);
120
Sven Schnellee44e81c2021-10-21 09:54:24 +0900121 KUNIT_EXPECT_FALSE(current_test, preemptible());
122 KUNIT_EXPECT_EQ(current_test, ret, rand1 / div_factor);
123 KUNIT_EXPECT_NE(current_test, krph_val, 0);
Abhishek Sagarf47cd9b2008-02-06 01:38:22 -0800124 krph_val = rand1;
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100125 return 0;
126}
127
128static struct kretprobe rp = {
129 .handler = return_handler,
Abhishek Sagarf47cd9b2008-02-06 01:38:22 -0800130 .entry_handler = entry_handler,
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100131 .kp.symbol_name = "kprobe_target"
132};
133
Sven Schnellee44e81c2021-10-21 09:54:24 +0900134static void test_kretprobe(struct kunit *test)
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100135{
Sven Schnellee44e81c2021-10-21 09:54:24 +0900136 current_test = test;
137 KUNIT_EXPECT_EQ(test, 0, register_kretprobe(&rp));
138 target(rand1);
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100139 unregister_kretprobe(&rp);
Sven Schnellee44e81c2021-10-21 09:54:24 +0900140 KUNIT_EXPECT_EQ(test, krph_val, rand1);
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100141}
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800142
143static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
144{
145 unsigned long ret = regs_return_value(regs);
146
Sven Schnellee44e81c2021-10-21 09:54:24 +0900147 KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
148 KUNIT_EXPECT_NE(current_test, krph_val, 0);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800149 krph_val = rand1;
150 return 0;
151}
152
153static struct kretprobe rp2 = {
154 .handler = return_handler2,
155 .entry_handler = entry_handler,
156 .kp.symbol_name = "kprobe_target2"
157};
158
Sven Schnellee44e81c2021-10-21 09:54:24 +0900159static void test_kretprobes(struct kunit *test)
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800160{
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800161 struct kretprobe *rps[2] = {&rp, &rp2};
162
Sven Schnellee44e81c2021-10-21 09:54:24 +0900163 current_test = test;
Masami Hiramatsufd02e6f2010-10-14 12:10:24 +0900164 /* addr and flags should be cleard for reusing kprobe. */
165 rp.kp.addr = NULL;
166 rp.kp.flags = 0;
Sven Schnellee44e81c2021-10-21 09:54:24 +0900167 KUNIT_EXPECT_EQ(test, 0, register_kretprobes(rps, 2));
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800168
169 krph_val = 0;
Sven Schnellee44e81c2021-10-21 09:54:24 +0900170 target(rand1);
171 KUNIT_EXPECT_EQ(test, krph_val, rand1);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800172
173 krph_val = 0;
Sven Schnellee44e81c2021-10-21 09:54:24 +0900174 target2(rand1);
175 KUNIT_EXPECT_EQ(test, krph_val, rand1);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800176 unregister_kretprobes(rps, 2);
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800177}
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100178#endif /* CONFIG_KRETPROBES */
179
Sven Schnellee44e81c2021-10-21 09:54:24 +0900180static int kprobes_test_init(struct kunit *test)
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100181{
Masami Hiramatsu8e114402009-01-06 14:41:47 -0800182 target = kprobe_target;
Masami Hiramatsu12da3b82009-01-06 14:41:48 -0800183 target2 = kprobe_target2;
Masami Hiramatsu8e114402009-01-06 14:41:47 -0800184
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100185 do {
Akinobu Mita6d65df32013-04-29 16:21:30 -0700186 rand1 = prandom_u32();
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100187 } while (rand1 <= div_factor);
Ananth N Mavinakayanahalli8c1c9352008-01-30 13:32:53 +0100188 return 0;
189}
Sven Schnellee44e81c2021-10-21 09:54:24 +0900190
191static struct kunit_case kprobes_testcases[] = {
192 KUNIT_CASE(test_kprobe),
193 KUNIT_CASE(test_kprobes),
194#ifdef CONFIG_KRETPROBES
195 KUNIT_CASE(test_kretprobe),
196 KUNIT_CASE(test_kretprobes),
197#endif
198 {}
199};
200
201static struct kunit_suite kprobes_test_suite = {
202 .name = "kprobes_test",
203 .init = kprobes_test_init,
204 .test_cases = kprobes_testcases,
205};
206
207kunit_test_suites(&kprobes_test_suite);
208
209MODULE_LICENSE("GPL");