1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * User Events Dyn Events Test Program
4  *
5  * Copyright (c) 2021 Beau Belgrave <beaub@linux.microsoft.com>
6  */
7 
8 #include <errno.h>
9 #include <linux/user_events.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <fcntl.h>
13 #include <sys/ioctl.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16 
17 #include "../kselftest_harness.h"
18 
19 const char *dyn_file = "/sys/kernel/debug/tracing/dynamic_events";
20 const char *clear = "!u:__test_event";
21 
Append(const char * value)22 static int Append(const char *value)
23 {
24 	int fd = open(dyn_file, O_RDWR | O_APPEND);
25 	int ret = write(fd, value, strlen(value));
26 
27 	close(fd);
28 	return ret;
29 }
30 
31 #define CLEAR() \
32 do { \
33 	int ret = Append(clear); \
34 	if (ret == -1) \
35 		ASSERT_EQ(ENOENT, errno); \
36 } while (0)
37 
38 #define TEST_PARSE(x) \
39 do { \
40 	ASSERT_NE(-1, Append(x)); \
41 	CLEAR(); \
42 } while (0)
43 
44 #define TEST_NPARSE(x) ASSERT_EQ(-1, Append(x))
45 
FIXTURE(user)46 FIXTURE(user) {
47 };
48 
FIXTURE_SETUP(user)49 FIXTURE_SETUP(user) {
50 	CLEAR();
51 }
52 
FIXTURE_TEARDOWN(user)53 FIXTURE_TEARDOWN(user) {
54 	CLEAR();
55 }
56 
TEST_F(user,basic_types)57 TEST_F(user, basic_types) {
58 	/* All should work */
59 	TEST_PARSE("u:__test_event u64 a");
60 	TEST_PARSE("u:__test_event u32 a");
61 	TEST_PARSE("u:__test_event u16 a");
62 	TEST_PARSE("u:__test_event u8 a");
63 	TEST_PARSE("u:__test_event char a");
64 	TEST_PARSE("u:__test_event unsigned char a");
65 	TEST_PARSE("u:__test_event int a");
66 	TEST_PARSE("u:__test_event unsigned int a");
67 	TEST_PARSE("u:__test_event short a");
68 	TEST_PARSE("u:__test_event unsigned short a");
69 	TEST_PARSE("u:__test_event char[20] a");
70 	TEST_PARSE("u:__test_event unsigned char[20] a");
71 	TEST_PARSE("u:__test_event char[0x14] a");
72 	TEST_PARSE("u:__test_event unsigned char[0x14] a");
73 	/* Bad size format should fail */
74 	TEST_NPARSE("u:__test_event char[aa] a");
75 	/* Large size should fail */
76 	TEST_NPARSE("u:__test_event char[9999] a");
77 	/* Long size string should fail */
78 	TEST_NPARSE("u:__test_event char[0x0000000000001] a");
79 }
80 
TEST_F(user,loc_types)81 TEST_F(user, loc_types) {
82 	/* All should work */
83 	TEST_PARSE("u:__test_event __data_loc char[] a");
84 	TEST_PARSE("u:__test_event __data_loc unsigned char[] a");
85 	TEST_PARSE("u:__test_event __rel_loc char[] a");
86 	TEST_PARSE("u:__test_event __rel_loc unsigned char[] a");
87 }
88 
TEST_F(user,size_types)89 TEST_F(user, size_types) {
90 	/* Should work */
91 	TEST_PARSE("u:__test_event struct custom a 20");
92 	/* Size not specified on struct should fail */
93 	TEST_NPARSE("u:__test_event struct custom a");
94 	/* Size specified on non-struct should fail */
95 	TEST_NPARSE("u:__test_event char a 20");
96 }
97 
TEST_F(user,flags)98 TEST_F(user, flags) {
99 	/* Should work */
100 	TEST_PARSE("u:__test_event:BPF_ITER u32 a");
101 	/* Forward compat */
102 	TEST_PARSE("u:__test_event:BPF_ITER,FLAG_FUTURE u32 a");
103 }
104 
TEST_F(user,matching)105 TEST_F(user, matching) {
106 	/* Register */
107 	ASSERT_NE(-1, Append("u:__test_event struct custom a 20"));
108 	/* Should not match */
109 	TEST_NPARSE("!u:__test_event struct custom b");
110 	/* Should match */
111 	TEST_PARSE("!u:__test_event struct custom a");
112 	/* Multi field reg */
113 	ASSERT_NE(-1, Append("u:__test_event u32 a; u32 b"));
114 	/* Non matching cases */
115 	TEST_NPARSE("!u:__test_event u32 a");
116 	TEST_NPARSE("!u:__test_event u32 b");
117 	TEST_NPARSE("!u:__test_event u32 a; u32 ");
118 	TEST_NPARSE("!u:__test_event u32 a; u32 a");
119 	/* Matching case */
120 	TEST_PARSE("!u:__test_event u32 a; u32 b");
121 	/* Register */
122 	ASSERT_NE(-1, Append("u:__test_event u32 a; u32 b"));
123 	/* Ensure trailing semi-colon case */
124 	TEST_PARSE("!u:__test_event u32 a; u32 b;");
125 }
126 
main(int argc,char ** argv)127 int main(int argc, char **argv)
128 {
129 	return test_harness_run(argc, argv);
130 }
131