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 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 46 FIXTURE(user) { 47 }; 48 49 FIXTURE_SETUP(user) { 50 CLEAR(); 51 } 52 53 FIXTURE_TEARDOWN(user) { 54 CLEAR(); 55 } 56 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 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 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 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 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 127 int main(int argc, char **argv) 128 { 129 return test_harness_run(argc, argv); 130 } 131