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> 15 #include <linux/user_events.h> 16 17 /* Assumes debugfs is mounted */ 18 const char *data_file = "/sys/kernel/debug/tracing/user_events_data"; 19 const char *status_file = "/sys/kernel/debug/tracing/user_events_status"; 20 21 static int event_status(char **status) 22 { 23 int fd = open(status_file, O_RDONLY); 24 25 *status = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ, 26 MAP_SHARED, fd, 0); 27 28 close(fd); 29 30 if (*status == MAP_FAILED) 31 return -1; 32 33 return 0; 34 } 35 36 static int event_reg(int fd, const char *command, int *status, int *write) 37 { 38 struct user_reg reg = {0}; 39 40 reg.size = sizeof(reg); 41 reg.name_args = (__u64)command; 42 43 if (ioctl(fd, DIAG_IOCSREG, ®) == -1) 44 return -1; 45 46 *status = reg.status_index; 47 *write = reg.write_index; 48 49 return 0; 50 } 51 52 int main(int argc, char **argv) 53 { 54 int data_fd, status, write; 55 char *status_page; 56 struct iovec io[2]; 57 __u32 count = 0; 58 59 if (event_status(&status_page) == -1) 60 return errno; 61 62 data_fd = open(data_file, O_RDWR); 63 64 if (event_reg(data_fd, "test u32 count", &status, &write) == -1) 65 return errno; 66 67 /* Setup iovec */ 68 io[0].iov_base = &write; 69 io[0].iov_len = sizeof(write); 70 io[1].iov_base = &count; 71 io[1].iov_len = sizeof(count); 72 73 ask: 74 printf("Press enter to check status...\n"); 75 getchar(); 76 77 /* Check if anyone is listening */ 78 if (status_page[status]) { 79 /* Yep, trace out our data */ 80 writev(data_fd, (const struct iovec *)io, 2); 81 82 /* Increase the count */ 83 count++; 84 85 printf("Something was attached, wrote data\n"); 86 } 87 88 goto ask; 89 90 return 0; 91 } 92