test_fprobe.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * test_fprobe.c - simple sanity test for fprobe
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/fprobe.h>
  7. #include <linux/random.h>
  8. #include <kunit/test.h>
  9. #define div_factor 3
  10. static struct kunit *current_test;
  11. static u32 rand1, entry_only_val, entry_val, exit_val;
  12. static u32 entry_only_count, entry_count, exit_count;
  13. /* Use indirect calls to avoid inlining the target functions */
  14. static u32 (*target)(u32 value);
  15. static u32 (*target2)(u32 value);
  16. static unsigned long target_ip;
  17. static unsigned long target2_ip;
  18. static int entry_return_value;
  19. static noinline u32 fprobe_selftest_target(u32 value)
  20. {
  21. return (value / div_factor);
  22. }
  23. static noinline u32 fprobe_selftest_target2(u32 value)
  24. {
  25. return (value / div_factor) + 1;
  26. }
  27. static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip,
  28. unsigned long ret_ip,
  29. struct ftrace_regs *fregs, void *data)
  30. {
  31. KUNIT_EXPECT_FALSE(current_test, preemptible());
  32. /* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */
  33. if (ip != target_ip)
  34. KUNIT_EXPECT_EQ(current_test, ip, target2_ip);
  35. entry_val = (rand1 / div_factor);
  36. if (fp->entry_data_size) {
  37. KUNIT_EXPECT_NOT_NULL(current_test, data);
  38. if (data)
  39. *(u32 *)data = entry_val;
  40. } else
  41. KUNIT_EXPECT_NULL(current_test, data);
  42. return entry_return_value;
  43. }
  44. static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip,
  45. unsigned long ret_ip,
  46. struct ftrace_regs *fregs, void *data)
  47. {
  48. unsigned long ret = ftrace_regs_get_return_value(fregs);
  49. KUNIT_EXPECT_FALSE(current_test, preemptible());
  50. if (ip != target_ip) {
  51. KUNIT_EXPECT_EQ(current_test, ip, target2_ip);
  52. KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
  53. } else
  54. KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor));
  55. KUNIT_EXPECT_EQ(current_test, entry_val, (rand1 / div_factor));
  56. exit_val = entry_val + div_factor;
  57. if (fp->entry_data_size) {
  58. KUNIT_EXPECT_NOT_NULL(current_test, data);
  59. if (data)
  60. KUNIT_EXPECT_EQ(current_test, *(u32 *)data, entry_val);
  61. } else
  62. KUNIT_EXPECT_NULL(current_test, data);
  63. }
  64. /* Test entry only (no rethook) */
  65. static void test_fprobe_entry(struct kunit *test)
  66. {
  67. struct fprobe fp_entry = {
  68. .entry_handler = fp_entry_handler,
  69. };
  70. current_test = test;
  71. /* Before register, unregister should be failed. */
  72. KUNIT_EXPECT_NE(test, 0, unregister_fprobe(&fp_entry));
  73. KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp_entry, "fprobe_selftest_target*", NULL));
  74. entry_val = 0;
  75. exit_val = 0;
  76. target(rand1);
  77. KUNIT_EXPECT_NE(test, 0, entry_val);
  78. KUNIT_EXPECT_EQ(test, 0, exit_val);
  79. entry_val = 0;
  80. exit_val = 0;
  81. target2(rand1);
  82. KUNIT_EXPECT_NE(test, 0, entry_val);
  83. KUNIT_EXPECT_EQ(test, 0, exit_val);
  84. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp_entry));
  85. }
  86. static void test_fprobe(struct kunit *test)
  87. {
  88. struct fprobe fp = {
  89. .entry_handler = fp_entry_handler,
  90. .exit_handler = fp_exit_handler,
  91. };
  92. current_test = test;
  93. KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target*", NULL));
  94. entry_val = 0;
  95. exit_val = 0;
  96. target(rand1);
  97. KUNIT_EXPECT_NE(test, 0, entry_val);
  98. KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
  99. entry_val = 0;
  100. exit_val = 0;
  101. target2(rand1);
  102. KUNIT_EXPECT_NE(test, 0, entry_val);
  103. KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
  104. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
  105. }
  106. static void test_fprobe_syms(struct kunit *test)
  107. {
  108. static const char *syms[] = {"fprobe_selftest_target", "fprobe_selftest_target2"};
  109. struct fprobe fp = {
  110. .entry_handler = fp_entry_handler,
  111. .exit_handler = fp_exit_handler,
  112. };
  113. current_test = test;
  114. KUNIT_EXPECT_EQ(test, 0, register_fprobe_syms(&fp, syms, 2));
  115. entry_val = 0;
  116. exit_val = 0;
  117. target(rand1);
  118. KUNIT_EXPECT_NE(test, 0, entry_val);
  119. KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
  120. entry_val = 0;
  121. exit_val = 0;
  122. target2(rand1);
  123. KUNIT_EXPECT_NE(test, 0, entry_val);
  124. KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
  125. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
  126. }
  127. /* Test private entry_data */
  128. static void test_fprobe_data(struct kunit *test)
  129. {
  130. struct fprobe fp = {
  131. .entry_handler = fp_entry_handler,
  132. .exit_handler = fp_exit_handler,
  133. .entry_data_size = sizeof(u32),
  134. };
  135. current_test = test;
  136. KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target", NULL));
  137. target(rand1);
  138. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
  139. }
  140. static void test_fprobe_skip(struct kunit *test)
  141. {
  142. struct fprobe fp = {
  143. .entry_handler = fp_entry_handler,
  144. .exit_handler = fp_exit_handler,
  145. };
  146. current_test = test;
  147. KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target", NULL));
  148. entry_return_value = 1;
  149. entry_val = 0;
  150. exit_val = 0;
  151. target(rand1);
  152. KUNIT_EXPECT_NE(test, 0, entry_val);
  153. KUNIT_EXPECT_EQ(test, 0, exit_val);
  154. KUNIT_EXPECT_EQ(test, 0, fp.nmissed);
  155. entry_return_value = 0;
  156. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
  157. }
  158. /* Handler for fprobe entry only case */
  159. static notrace int entry_only_handler(struct fprobe *fp, unsigned long ip,
  160. unsigned long ret_ip,
  161. struct ftrace_regs *fregs, void *data)
  162. {
  163. KUNIT_EXPECT_FALSE(current_test, preemptible());
  164. KUNIT_EXPECT_EQ(current_test, ip, target_ip);
  165. entry_only_count++;
  166. entry_only_val = (rand1 / div_factor);
  167. return 0;
  168. }
  169. static notrace int fprobe_entry_multi_handler(struct fprobe *fp, unsigned long ip,
  170. unsigned long ret_ip,
  171. struct ftrace_regs *fregs,
  172. void *data)
  173. {
  174. KUNIT_EXPECT_FALSE(current_test, preemptible());
  175. KUNIT_EXPECT_EQ(current_test, ip, target_ip);
  176. entry_count++;
  177. entry_val = (rand1 / div_factor);
  178. return 0;
  179. }
  180. static notrace void fprobe_exit_multi_handler(struct fprobe *fp, unsigned long ip,
  181. unsigned long ret_ip,
  182. struct ftrace_regs *fregs,
  183. void *data)
  184. {
  185. unsigned long ret = ftrace_regs_get_return_value(fregs);
  186. KUNIT_EXPECT_FALSE(current_test, preemptible());
  187. KUNIT_EXPECT_EQ(current_test, ip, target_ip);
  188. KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor));
  189. exit_count++;
  190. exit_val = ret;
  191. }
  192. static void check_fprobe_multi(struct kunit *test)
  193. {
  194. entry_only_count = entry_count = exit_count = 0;
  195. entry_only_val = entry_val = exit_val = 0;
  196. target(rand1);
  197. /* Verify all handlers were called */
  198. KUNIT_EXPECT_EQ(test, 1, entry_only_count);
  199. KUNIT_EXPECT_EQ(test, 1, entry_count);
  200. KUNIT_EXPECT_EQ(test, 1, exit_count);
  201. /* Verify values are correct */
  202. KUNIT_EXPECT_EQ(test, (rand1 / div_factor), entry_only_val);
  203. KUNIT_EXPECT_EQ(test, (rand1 / div_factor), entry_val);
  204. KUNIT_EXPECT_EQ(test, (rand1 / div_factor), exit_val);
  205. }
  206. /* Test multiple fprobes hooking the same target function */
  207. static void test_fprobe_multi(struct kunit *test)
  208. {
  209. struct fprobe fp1 = {
  210. .entry_handler = fprobe_entry_multi_handler,
  211. .exit_handler = fprobe_exit_multi_handler,
  212. };
  213. struct fprobe fp2 = {
  214. .entry_handler = entry_only_handler,
  215. };
  216. current_test = test;
  217. /* Test Case 1: Register in order 1 -> 2 */
  218. KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp1, "fprobe_selftest_target", NULL));
  219. KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp2, "fprobe_selftest_target", NULL));
  220. check_fprobe_multi(test);
  221. /* Unregister all */
  222. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp1));
  223. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp2));
  224. /* Test Case 2: Register in order 2 -> 1 */
  225. KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp2, "fprobe_selftest_target", NULL));
  226. KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp1, "fprobe_selftest_target", NULL));
  227. check_fprobe_multi(test);
  228. /* Unregister all */
  229. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp1));
  230. KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp2));
  231. }
  232. static unsigned long get_ftrace_location(void *func)
  233. {
  234. unsigned long size, addr = (unsigned long)func;
  235. if (!kallsyms_lookup_size_offset(addr, &size, NULL) || !size)
  236. return 0;
  237. return ftrace_location_range(addr, addr + size - 1);
  238. }
  239. static int fprobe_test_init(struct kunit *test)
  240. {
  241. rand1 = get_random_u32_above(div_factor);
  242. target = fprobe_selftest_target;
  243. target2 = fprobe_selftest_target2;
  244. target_ip = get_ftrace_location(target);
  245. target2_ip = get_ftrace_location(target2);
  246. return 0;
  247. }
  248. static struct kunit_case fprobe_testcases[] = {
  249. KUNIT_CASE(test_fprobe_entry),
  250. KUNIT_CASE(test_fprobe),
  251. KUNIT_CASE(test_fprobe_syms),
  252. KUNIT_CASE(test_fprobe_data),
  253. KUNIT_CASE(test_fprobe_skip),
  254. KUNIT_CASE(test_fprobe_multi),
  255. {}
  256. };
  257. static struct kunit_suite fprobe_test_suite = {
  258. .name = "fprobe_test",
  259. .init = fprobe_test_init,
  260. .test_cases = fprobe_testcases,
  261. };
  262. kunit_test_suites(&fprobe_test_suite);