/* SPDX-License-Identifier: GPL-2.0 */

#include "perf-sys.h"
#include "util/cloexec.h"
#include "util/evlist.h"
#include "util/evsel.h"
#include "util/parse-events.h"
#include "util/perf_api_probe.h"
#include <perf/cpumap.h>
#include <errno.h>

typedef void (*setup_probe_fn_t)(struct evsel *evsel);

static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
{
	struct evlist *evlist;
	struct evsel *evsel;
	unsigned long flags = perf_event_open_cloexec_flag();
	int err = -EAGAIN, fd;
	static pid_t pid = -1;

	evlist = evlist__new();
	if (!evlist)
		return -ENOMEM;

	if (parse_events(evlist, str, NULL))
		goto out_delete;

	evsel = evlist__first(evlist);

	while (1) {
		fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
		if (fd < 0) {
			if (pid == -1 && errno == EACCES) {
				pid = 0;
				continue;
			}
			goto out_delete;
		}
		break;
	}
	close(fd);

	fn(evsel);

	fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
	if (fd < 0) {
		if (errno == EINVAL)
			err = -EINVAL;
		goto out_delete;
	}
	close(fd);
	err = 0;

out_delete:
	evlist__delete(evlist);
	return err;
}

static bool perf_probe_api(setup_probe_fn_t fn)
{
	const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL};
	struct perf_cpu_map *cpus;
	int cpu, ret, i = 0;

	cpus = perf_cpu_map__new(NULL);
	if (!cpus)
		return false;
	cpu = cpus->map[0];
	perf_cpu_map__put(cpus);

	do {
		ret = perf_do_probe_api(fn, cpu, try[i++]);
		if (!ret)
			return true;
	} while (ret == -EAGAIN && try[i]);

	return false;
}

static void perf_probe_sample_identifier(struct evsel *evsel)
{
	evsel->core.attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
}

static void perf_probe_comm_exec(struct evsel *evsel)
{
	evsel->core.attr.comm_exec = 1;
}

static void perf_probe_context_switch(struct evsel *evsel)
{
	evsel->core.attr.context_switch = 1;
}

static void perf_probe_text_poke(struct evsel *evsel)
{
	evsel->core.attr.text_poke = 1;
}

static void perf_probe_build_id(struct evsel *evsel)
{
	evsel->core.attr.build_id = 1;
}

static void perf_probe_cgroup(struct evsel *evsel)
{
	evsel->core.attr.cgroup = 1;
}

bool perf_can_sample_identifier(void)
{
	return perf_probe_api(perf_probe_sample_identifier);
}

bool perf_can_comm_exec(void)
{
	return perf_probe_api(perf_probe_comm_exec);
}

bool perf_can_record_switch_events(void)
{
	return perf_probe_api(perf_probe_context_switch);
}

bool perf_can_record_text_poke_events(void)
{
	return perf_probe_api(perf_probe_text_poke);
}

bool perf_can_record_cpu_wide(void)
{
	struct perf_event_attr attr = {
		.type = PERF_TYPE_SOFTWARE,
		.config = PERF_COUNT_SW_CPU_CLOCK,
		.exclude_kernel = 1,
	};
	struct perf_cpu_map *cpus;
	int cpu, fd;

	cpus = perf_cpu_map__new(NULL);
	if (!cpus)
		return false;
	cpu = cpus->map[0];
	perf_cpu_map__put(cpus);

	fd = sys_perf_event_open(&attr, -1, cpu, -1, 0);
	if (fd < 0)
		return false;
	close(fd);

	return true;
}

/*
 * Architectures are expected to know if AUX area sampling is supported by the
 * hardware. Here we check for kernel support.
 */
bool perf_can_aux_sample(void)
{
	struct perf_event_attr attr = {
		.size = sizeof(struct perf_event_attr),
		.exclude_kernel = 1,
		/*
		 * Non-zero value causes the kernel to calculate the effective
		 * attribute size up to that byte.
		 */
		.aux_sample_size = 1,
	};
	int fd;

	fd = sys_perf_event_open(&attr, -1, 0, -1, 0);
	/*
	 * If the kernel attribute is big enough to contain aux_sample_size
	 * then we assume that it is supported. We are relying on the kernel to
	 * validate the attribute size before anything else that could be wrong.
	 */
	if (fd < 0 && errno == E2BIG)
		return false;
	if (fd >= 0)
		close(fd);

	return true;
}

bool perf_can_record_build_id(void)
{
	return perf_probe_api(perf_probe_build_id);
}

bool perf_can_record_cgroup(void)
{
	return perf_probe_api(perf_probe_cgroup);
}
