162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2021, Microsoft Corporation.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Authors:
662306a36Sopenharmony_ci *   Beau Belgrave <beaub@linux.microsoft.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <errno.h>
1062306a36Sopenharmony_ci#include <sys/ioctl.h>
1162306a36Sopenharmony_ci#include <sys/mman.h>
1262306a36Sopenharmony_ci#include <sys/uio.h>
1362306a36Sopenharmony_ci#include <fcntl.h>
1462306a36Sopenharmony_ci#include <stdio.h>
1562306a36Sopenharmony_ci#include <unistd.h>
1662306a36Sopenharmony_ci#include <linux/user_events.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciconst char *data_file = "/sys/kernel/tracing/user_events_data";
1962306a36Sopenharmony_ciint enabled = 0;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic int event_reg(int fd, const char *command, int *write, int *enabled)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	struct user_reg reg = {0};
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	reg.size = sizeof(reg);
2662306a36Sopenharmony_ci	reg.enable_bit = 31;
2762306a36Sopenharmony_ci	reg.enable_size = sizeof(*enabled);
2862306a36Sopenharmony_ci	reg.enable_addr = (__u64)enabled;
2962306a36Sopenharmony_ci	reg.name_args = (__u64)command;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	if (ioctl(fd, DIAG_IOCSREG, &reg) == -1)
3262306a36Sopenharmony_ci		return -1;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	*write = reg.write_index;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	return 0;
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ciint main(int argc, char **argv)
4062306a36Sopenharmony_ci{
4162306a36Sopenharmony_ci	int data_fd, write;
4262306a36Sopenharmony_ci	struct iovec io[2];
4362306a36Sopenharmony_ci	__u32 count = 0;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	data_fd = open(data_file, O_RDWR);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	if (event_reg(data_fd, "test u32 count", &write, &enabled) == -1)
4862306a36Sopenharmony_ci		return errno;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	/* Setup iovec */
5162306a36Sopenharmony_ci	io[0].iov_base = &write;
5262306a36Sopenharmony_ci	io[0].iov_len = sizeof(write);
5362306a36Sopenharmony_ci	io[1].iov_base = &count;
5462306a36Sopenharmony_ci	io[1].iov_len = sizeof(count);
5562306a36Sopenharmony_ciask:
5662306a36Sopenharmony_ci	printf("Press enter to check status...\n");
5762306a36Sopenharmony_ci	getchar();
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	/* Check if anyone is listening */
6062306a36Sopenharmony_ci	if (enabled) {
6162306a36Sopenharmony_ci		/* Yep, trace out our data */
6262306a36Sopenharmony_ci		writev(data_fd, (const struct iovec *)io, 2);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci		/* Increase the count */
6562306a36Sopenharmony_ci		count++;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci		printf("Something was attached, wrote data\n");
6862306a36Sopenharmony_ci	}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	goto ask;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	return 0;
7362306a36Sopenharmony_ci}
74