// SPDX-License-Identifier: GPL-2.0
/*
 * User Events Perf Events Test Program
 *
 * Copyright (c) 2021 Beau Belgrave <beaub@linux.microsoft.com>
 */

#include <errno.h>
#include <linux/user_events.h>
#include <linux/perf_event.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <asm/unistd.h>

#include "../kselftest_harness.h"

const char *data_file = "/sys/kernel/debug/tracing/user_events_data";
const char *status_file = "/sys/kernel/debug/tracing/user_events_status";
const char *id_file = "/sys/kernel/debug/tracing/events/user_events/__test_event/id";
const char *fmt_file = "/sys/kernel/debug/tracing/events/user_events/__test_event/format";

struct event {
	__u32 index;
	__u32 field1;
	__u32 field2;
};

static long perf_event_open(struct perf_event_attr *pe, pid_t pid,
			    int cpu, int group_fd, unsigned long flags)
{
	return syscall(__NR_perf_event_open, pe, pid, cpu, group_fd, flags);
}

static inline int status_check(char *status_page, int status_bit)
{
	return status_page[status_bit >> 3] & (1 << (status_bit & 7));
}

static int get_id(void)
{
	FILE *fp = fopen(id_file, "r");
	int ret, id = 0;

	if (!fp)
		return -1;

	ret = fscanf(fp, "%d", &id);
	fclose(fp);

	if (ret != 1)
		return -1;

	return id;
}

static int get_offset(void)
{
	FILE *fp = fopen(fmt_file, "r");
	int ret, c, last = 0, offset = 0;

	if (!fp)
		return -1;

	/* Read until empty line */
	while (true) {
		c = getc(fp);

		if (c == EOF)
			break;

		if (last == '\n' && c == '\n')
			break;

		last = c;
	}

	ret = fscanf(fp, "\tfield:u32 field1;\toffset:%d;", &offset);
	fclose(fp);

	if (ret != 1)
		return -1;

	return offset;
}

FIXTURE(user) {
	int status_fd;
	int data_fd;
};

FIXTURE_SETUP(user) {
	self->status_fd = open(status_file, O_RDONLY);
	ASSERT_NE(-1, self->status_fd);

	self->data_fd = open(data_file, O_RDWR);
	ASSERT_NE(-1, self->data_fd);
}

FIXTURE_TEARDOWN(user) {
	close(self->status_fd);
	close(self->data_fd);
}

TEST_F(user, perf_write) {
	struct perf_event_attr pe = {0};
	struct user_reg reg = {0};
	int page_size = sysconf(_SC_PAGESIZE);
	char *status_page;
	struct event event;
	struct perf_event_mmap_page *perf_page;
	int id, fd, offset;
	__u32 *val;

	reg.size = sizeof(reg);
	reg.name_args = (__u64)"__test_event u32 field1; u32 field2";

	status_page = mmap(NULL, page_size, PROT_READ, MAP_SHARED,
			   self->status_fd, 0);
	ASSERT_NE(MAP_FAILED, status_page);

	/* Register should work */
	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
	ASSERT_EQ(0, reg.write_index);
	ASSERT_NE(0, reg.status_bit);
	ASSERT_EQ(0, status_check(status_page, reg.status_bit));

	/* Id should be there */
	id = get_id();
	ASSERT_NE(-1, id);
	offset = get_offset();
	ASSERT_NE(-1, offset);

	pe.type = PERF_TYPE_TRACEPOINT;
	pe.size = sizeof(pe);
	pe.config = id;
	pe.sample_type = PERF_SAMPLE_RAW;
	pe.sample_period = 1;
	pe.wakeup_events = 1;

	/* Tracepoint attach should work */
	fd = perf_event_open(&pe, 0, -1, -1, 0);
	ASSERT_NE(-1, fd);

	perf_page = mmap(NULL, page_size * 2, PROT_READ, MAP_SHARED, fd, 0);
	ASSERT_NE(MAP_FAILED, perf_page);

	/* Status should be updated */
	ASSERT_NE(0, status_check(status_page, reg.status_bit));

	event.index = reg.write_index;
	event.field1 = 0xc001;
	event.field2 = 0xc01a;

	/* Ensure write shows up at correct offset */
	ASSERT_NE(-1, write(self->data_fd, &event, sizeof(event)));
	val = (void *)(((char *)perf_page) + perf_page->data_offset);
	ASSERT_EQ(PERF_RECORD_SAMPLE, *val);
	/* Skip over header and size, move to offset */
	val += 3;
	val = (void *)((char *)val) + offset;
	/* Ensure correct */
	ASSERT_EQ(event.field1, *val++);
	ASSERT_EQ(event.field2, *val++);
}

int main(int argc, char **argv)
{
	return test_harness_run(argc, argv);
}
