// SPDX-License-Identifier: GPL-2.0-only
#define _GNU_SOURCE

#include <dirent.h>
#include <sched.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/types.h>

#include <linux/perf_event.h>

#include "kselftest_harness.h"

#define RB_SIZE		0x3000
#define AUX_SIZE	0x10000
#define AUX_OFFS	0x4000

#define HOLE_SIZE	0x1000

/* Reserve space for rb, aux with space for shrink-beyond-vma testing. */
#define REGION_SIZE	(2 * RB_SIZE + 2 * AUX_SIZE)
#define REGION_AUX_OFFS (2 * RB_SIZE)

#define MAP_BASE	1
#define MAP_AUX		2

#define EVENT_SRC_DIR	"/sys/bus/event_source/devices"

FIXTURE(perf_mmap)
{
	int		fd;
	void		*ptr;
	void		*region;
};

FIXTURE_VARIANT(perf_mmap)
{
	bool		aux;
	unsigned long	ptr_size;
};

FIXTURE_VARIANT_ADD(perf_mmap, rb)
{
	.aux = false,
	.ptr_size = RB_SIZE,
};

FIXTURE_VARIANT_ADD(perf_mmap, aux)
{
	.aux = true,
	.ptr_size = AUX_SIZE,
};

static bool read_event_type(struct dirent *dent, __u32 *type)
{
	char typefn[512];
	FILE *fp;
	int res;

	snprintf(typefn, sizeof(typefn), "%s/%s/type", EVENT_SRC_DIR, dent->d_name);
	fp = fopen(typefn, "r");
	if (!fp)
		return false;

	res = fscanf(fp, "%u", type);
	fclose(fp);
	return res > 0;
}

FIXTURE_SETUP(perf_mmap)
{
	struct perf_event_attr attr = {
		.size		= sizeof(attr),
		.disabled	= 1,
		.exclude_kernel	= 1,
		.exclude_hv	= 1,
	};
	struct perf_event_attr attr_ok = {};
	unsigned int eacces = 0, map = 0;
	struct perf_event_mmap_page *rb;
	struct dirent *dent;
	void *aux, *region;
	DIR *dir;

	self->ptr = NULL;

	dir = opendir(EVENT_SRC_DIR);
	if (!dir)
		SKIP(return, "perf not available.");

	region = mmap(NULL, REGION_SIZE, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
	ASSERT_NE(region, MAP_FAILED);
	self->region = region;

	// Try to find a suitable event on this system
	while ((dent = readdir(dir))) {
		int fd;

		if (!read_event_type(dent, &attr.type))
			continue;

		fd = syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0);
		if (fd < 0) {
			if (errno == EACCES)
				eacces++;
			continue;
		}

		// Check whether the event supports mmap()
		rb = mmap(region, RB_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
		if (rb == MAP_FAILED) {
			close(fd);
			continue;
		}

		if (!map) {
			// Save the event in case that no AUX capable event is found
			attr_ok = attr;
			map = MAP_BASE;
		}

		if (!variant->aux)
			continue;

		rb->aux_offset = AUX_OFFS;
		rb->aux_size = AUX_SIZE;

		// Check whether it supports a AUX buffer
		aux = mmap(region + REGION_AUX_OFFS, AUX_SIZE, PROT_READ | PROT_WRITE,
			   MAP_SHARED | MAP_FIXED, fd, AUX_OFFS);
		if (aux == MAP_FAILED) {
			munmap(rb, RB_SIZE);
			close(fd);
			continue;
		}

		attr_ok = attr;
		map = MAP_AUX;
		munmap(aux, AUX_SIZE);
		munmap(rb, RB_SIZE);
		close(fd);
		break;
	}
	closedir(dir);

	if (!map) {
		if (!eacces)
			SKIP(return, "No mappable perf event found.");
		else
			SKIP(return, "No permissions for perf_event_open()");
	}

	self->fd = syscall(SYS_perf_event_open, &attr_ok, 0, -1, -1, 0);
	ASSERT_NE(self->fd, -1);

	rb = mmap(region, RB_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, self->fd, 0);
	ASSERT_NE(rb, MAP_FAILED);

	if (!variant->aux) {
		self->ptr = rb;
		return;
	}

	if (map != MAP_AUX)
		SKIP(return, "No AUX event found.");

	rb->aux_offset = AUX_OFFS;
	rb->aux_size = AUX_SIZE;
	aux = mmap(region + REGION_AUX_OFFS, AUX_SIZE, PROT_READ | PROT_WRITE,
		   MAP_SHARED | MAP_FIXED, self->fd, AUX_OFFS);
	ASSERT_NE(aux, MAP_FAILED);
	self->ptr = aux;
}

FIXTURE_TEARDOWN(perf_mmap)
{
	ASSERT_EQ(munmap(self->region, REGION_SIZE), 0);
	if (self->fd != -1)
		ASSERT_EQ(close(self->fd), 0);
}

TEST_F(perf_mmap, remap)
{
	void *tmp, *ptr = self->ptr;
	unsigned long size = variant->ptr_size;

	// Test the invalid remaps
	ASSERT_EQ(mremap(ptr, size, HOLE_SIZE, MREMAP_MAYMOVE), MAP_FAILED);
	ASSERT_EQ(mremap(ptr + HOLE_SIZE, size, HOLE_SIZE, MREMAP_MAYMOVE), MAP_FAILED);
	ASSERT_EQ(mremap(ptr + size - HOLE_SIZE, HOLE_SIZE, size, MREMAP_MAYMOVE), MAP_FAILED);
	// Shrink the end of the mapping such that we only unmap past end of the VMA,
	// which should succeed and poke a hole into the PROT_NONE region
	ASSERT_NE(mremap(ptr + size - HOLE_SIZE, size, HOLE_SIZE, MREMAP_MAYMOVE), MAP_FAILED);

	// Remap the whole buffer to a new address
	tmp = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
	ASSERT_NE(tmp, MAP_FAILED);

	// Try splitting offset 1 hole size into VMA, this should fail
	ASSERT_EQ(mremap(ptr + HOLE_SIZE, size - HOLE_SIZE, size - HOLE_SIZE,
			 MREMAP_MAYMOVE | MREMAP_FIXED, tmp), MAP_FAILED);
	// Remapping the whole thing should succeed fine
	ptr = mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, tmp);
	ASSERT_EQ(ptr, tmp);
	ASSERT_EQ(munmap(tmp, size), 0);
}

TEST_F(perf_mmap, unmap)
{
	unsigned long size = variant->ptr_size;

	// Try to poke holes into the mappings
	ASSERT_NE(munmap(self->ptr, HOLE_SIZE), 0);
	ASSERT_NE(munmap(self->ptr + HOLE_SIZE, HOLE_SIZE), 0);
	ASSERT_NE(munmap(self->ptr + size - HOLE_SIZE, HOLE_SIZE), 0);
}

TEST_F(perf_mmap, map)
{
	unsigned long size = variant->ptr_size;

	// Try to poke holes into the mappings by mapping anonymous memory over it
	ASSERT_EQ(mmap(self->ptr, HOLE_SIZE, PROT_READ | PROT_WRITE,
		       MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0), MAP_FAILED);
	ASSERT_EQ(mmap(self->ptr + HOLE_SIZE, HOLE_SIZE, PROT_READ | PROT_WRITE,
		       MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0), MAP_FAILED);
	ASSERT_EQ(mmap(self->ptr + size - HOLE_SIZE, HOLE_SIZE, PROT_READ | PROT_WRITE,
		       MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0), MAP_FAILED);
}

TEST_HARNESS_MAIN
