Commit | Line | Data |
---|---|---|
c57eb478 BB |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* | |
3 | * Copyright (c) 2021, Microsoft Corporation. | |
4 | * | |
5 | * Authors: | |
6 | * Beau Belgrave <beaub@linux.microsoft.com> | |
7 | */ | |
8 | ||
9 | #include <errno.h> | |
10 | #include <sys/ioctl.h> | |
11 | #include <sys/mman.h> | |
12 | #include <fcntl.h> | |
13 | #include <stdio.h> | |
14 | #include <unistd.h> | |
39d6d08b BB |
15 | #include <asm/bitsperlong.h> |
16 | #include <endian.h> | |
c57eb478 BB |
17 | #include <linux/user_events.h> |
18 | ||
39d6d08b BB |
19 | #if __BITS_PER_LONG == 64 |
20 | #define endian_swap(x) htole64(x) | |
21 | #else | |
22 | #define endian_swap(x) htole32(x) | |
23 | #endif | |
24 | ||
c57eb478 BB |
25 | /* Assumes debugfs is mounted */ |
26 | const char *data_file = "/sys/kernel/debug/tracing/user_events_data"; | |
27 | const char *status_file = "/sys/kernel/debug/tracing/user_events_status"; | |
28 | ||
39d6d08b | 29 | static int event_status(long **status) |
c57eb478 BB |
30 | { |
31 | int fd = open(status_file, O_RDONLY); | |
32 | ||
33 | *status = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ, | |
34 | MAP_SHARED, fd, 0); | |
35 | ||
36 | close(fd); | |
37 | ||
38 | if (*status == MAP_FAILED) | |
39 | return -1; | |
40 | ||
41 | return 0; | |
42 | } | |
43 | ||
39d6d08b BB |
44 | static int event_reg(int fd, const char *command, long *index, long *mask, |
45 | int *write) | |
c57eb478 BB |
46 | { |
47 | struct user_reg reg = {0}; | |
48 | ||
49 | reg.size = sizeof(reg); | |
50 | reg.name_args = (__u64)command; | |
51 | ||
52 | if (ioctl(fd, DIAG_IOCSREG, ®) == -1) | |
53 | return -1; | |
54 | ||
39d6d08b BB |
55 | *index = reg.status_bit / __BITS_PER_LONG; |
56 | *mask = endian_swap(1L << (reg.status_bit % __BITS_PER_LONG)); | |
c57eb478 BB |
57 | *write = reg.write_index; |
58 | ||
59 | return 0; | |
60 | } | |
61 | ||
62 | int main(int argc, char **argv) | |
63 | { | |
39d6d08b BB |
64 | int data_fd, write; |
65 | long index, mask; | |
66 | long *status_page; | |
c57eb478 BB |
67 | struct iovec io[2]; |
68 | __u32 count = 0; | |
69 | ||
70 | if (event_status(&status_page) == -1) | |
71 | return errno; | |
72 | ||
73 | data_fd = open(data_file, O_RDWR); | |
74 | ||
39d6d08b | 75 | if (event_reg(data_fd, "test u32 count", &index, &mask, &write) == -1) |
c57eb478 BB |
76 | return errno; |
77 | ||
78 | /* Setup iovec */ | |
79 | io[0].iov_base = &write; | |
80 | io[0].iov_len = sizeof(write); | |
81 | io[1].iov_base = &count; | |
82 | io[1].iov_len = sizeof(count); | |
83 | ||
84 | ask: | |
85 | printf("Press enter to check status...\n"); | |
86 | getchar(); | |
87 | ||
88 | /* Check if anyone is listening */ | |
39d6d08b | 89 | if (status_page[index] & mask) { |
c57eb478 BB |
90 | /* Yep, trace out our data */ |
91 | writev(data_fd, (const struct iovec *)io, 2); | |
92 | ||
93 | /* Increase the count */ | |
94 | count++; | |
95 | ||
96 | printf("Something was attached, wrote data\n"); | |
97 | } | |
98 | ||
99 | goto ask; | |
100 | ||
101 | return 0; | |
102 | } |