// SPDX-License-Identifier: GPL-2.0-only
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include <linux/align.h>
#include <linux/iommufd.h>
#include <linux/kernel.h>
#include <linux/limits.h>
#include <linux/log2.h>
#include <linux/mman.h>
#include <linux/overflow.h>
#include <linux/sizes.h>
#include <linux/types.h>
#include <linux/vfio.h>

#include <uuid/uuid.h>

#include "kselftest.h"
#include <libvfio.h>

static void vfio_pci_irq_set(struct vfio_pci_device *device,
			     u32 index, u32 vector, u32 count, int *fds)
{
	size_t argsz = sizeof(struct vfio_irq_set) + sizeof(int) * count;
	struct vfio_irq_set *irq;

	irq = calloc_assert(1, argsz);
	irq->argsz = argsz;
	irq->flags = VFIO_IRQ_SET_ACTION_TRIGGER;
	irq->index = index;
	irq->start = vector;
	irq->count = count;

	if (count) {
		irq->flags |= VFIO_IRQ_SET_DATA_EVENTFD;
		memcpy(irq->data, fds, sizeof(int) * count);
	} else {
		irq->flags |= VFIO_IRQ_SET_DATA_NONE;
	}

	ioctl_assert(device->fd, VFIO_DEVICE_SET_IRQS, irq);
	free(irq);
}

void vfio_pci_irq_trigger(struct vfio_pci_device *device, u32 index, u32 vector)
{
	struct vfio_irq_set irq = {
		.argsz = sizeof(irq),
		.flags = VFIO_IRQ_SET_ACTION_TRIGGER | VFIO_IRQ_SET_DATA_NONE,
		.index = index,
		.start = vector,
		.count = 1,
	};

	ioctl_assert(device->fd, VFIO_DEVICE_SET_IRQS, &irq);
}

static void check_supported_irq_index(u32 index)
{
	/* VFIO selftests only supports MSI and MSI-x for now. */
	VFIO_ASSERT_TRUE(index == VFIO_PCI_MSI_IRQ_INDEX ||
			 index == VFIO_PCI_MSIX_IRQ_INDEX,
			 "Unsupported IRQ index: %u\n", index);
}

void vfio_pci_irq_enable(struct vfio_pci_device *device, u32 index, u32 vector,
			 int count)
{
	int i;

	check_supported_irq_index(index);

	for (i = vector; i < vector + count; i++) {
		VFIO_ASSERT_LT(device->msi_eventfds[i], 0);
		device->msi_eventfds[i] = eventfd(0, 0);
		VFIO_ASSERT_GE(device->msi_eventfds[i], 0);
	}

	vfio_pci_irq_set(device, index, vector, count, device->msi_eventfds + vector);
}

void vfio_pci_irq_disable(struct vfio_pci_device *device, u32 index)
{
	int i;

	check_supported_irq_index(index);

	for (i = 0; i < ARRAY_SIZE(device->msi_eventfds); i++) {
		if (device->msi_eventfds[i] < 0)
			continue;

		VFIO_ASSERT_EQ(close(device->msi_eventfds[i]), 0);
		device->msi_eventfds[i] = -1;
	}

	vfio_pci_irq_set(device, index, 0, 0, NULL);
}

/*
 * Re-issue VFIO_DEVICE_SET_IRQS for an already-enabled vector range using
 * the existing eventfds.  Intended for drivers that need to re-arm device
 * interrupts after a VFIO_DEVICE_RESET, which tears down the kernel-side
 * IRQ trigger but leaves user-side eventfds intact.  Recreating the
 * eventfds would invalidate any test-fixture cache of the fd, so this
 * helper deliberately preserves them.
 */
void vfio_pci_irq_reenable(struct vfio_pci_device *device, u32 index,
			   u32 vector, int count)
{
	int i;

	check_supported_irq_index(index);

	for (i = vector; i < vector + count; i++)
		VFIO_ASSERT_GE(device->msi_eventfds[i], 0,
			       "vector %d eventfd not allocated\n", i);

	vfio_pci_irq_set(device, index, vector, count, device->msi_eventfds + vector);
}

static void vfio_pci_irq_get(struct vfio_pci_device *device, u32 index,
			     struct vfio_irq_info *irq_info)
{
	irq_info->argsz = sizeof(*irq_info);
	irq_info->index = index;

	ioctl_assert(device->fd, VFIO_DEVICE_GET_IRQ_INFO, irq_info);
}

static int vfio_device_feature_ioctl(int fd, u32 flags, void *data,
				     size_t data_size)
{
	size_t argsz = sizeof(struct vfio_device_feature) + data_size;
	struct vfio_device_feature *feature;
	int ret;

	feature = calloc_assert(1, argsz);
	memcpy(feature->data, data, data_size);

	feature->argsz = argsz;
	feature->flags = flags;

	ret = ioctl(fd, VFIO_DEVICE_FEATURE, feature);
	free(feature);

	return ret;
}

static void vfio_device_feature_set(int fd, u16 feature, void *data, size_t data_size)
{
	u32 flags = VFIO_DEVICE_FEATURE_SET | feature;
	int ret;

	ret = vfio_device_feature_ioctl(fd, flags, data, data_size);
	VFIO_ASSERT_EQ(ret, 0, "Failed to set feature %u\n", feature);
}

void vfio_device_set_vf_token(int fd, const char *vf_token)
{
	uuid_t token_uuid = {0};

	VFIO_ASSERT_NOT_NULL(vf_token, "vf_token is NULL");
	VFIO_ASSERT_EQ(uuid_parse(vf_token, token_uuid), 0);

	vfio_device_feature_set(fd, VFIO_DEVICE_FEATURE_PCI_VF_TOKEN,
				token_uuid, sizeof(uuid_t));
}

static void vfio_pci_region_get(struct vfio_pci_device *device, int index,
				struct vfio_region_info *info)
{
	memset(info, 0, sizeof(*info));

	info->argsz = sizeof(*info);
	info->index = index;

	ioctl_assert(device->fd, VFIO_DEVICE_GET_REGION_INFO, info);
}

static void vfio_pci_bar_map(struct vfio_pci_device *device, int index)
{
	struct vfio_pci_bar *bar = &device->bars[index];
	size_t align, size;
	int prot = 0;
	void *vaddr;

	VFIO_ASSERT_LT(index, PCI_STD_NUM_BARS);
	VFIO_ASSERT_NULL(bar->vaddr);
	VFIO_ASSERT_TRUE(bar->info.flags & VFIO_REGION_INFO_FLAG_MMAP);
	VFIO_ASSERT_TRUE(is_power_of_2(bar->info.size));

	if (bar->info.flags & VFIO_REGION_INFO_FLAG_READ)
		prot |= PROT_READ;
	if (bar->info.flags & VFIO_REGION_INFO_FLAG_WRITE)
		prot |= PROT_WRITE;

	size = bar->info.size;

	/*
	 * Align BAR mmaps to improve page fault granularity during potential
	 * subsequent IOMMU mapping of these BAR vaddr. 1G for x86 is the
	 * largest hugepage size across any architecture, so no benefit from
	 * larger alignment. BARs smaller than 1G will be aligned by their
	 * power-of-two size, guaranteeing sufficient alignment for smaller
	 * hugepages, if present.
	 */
	align = min_t(size_t, size, SZ_1G);

	vaddr = mmap_reserve(size, align, 0);
	bar->vaddr = mmap(vaddr, size, prot, MAP_SHARED | MAP_FIXED,
			  device->fd, bar->info.offset);
	VFIO_ASSERT_NE(bar->vaddr, MAP_FAILED);

	madvise(bar->vaddr, size, MADV_HUGEPAGE);
}

static void vfio_pci_bar_unmap(struct vfio_pci_device *device, int index)
{
	struct vfio_pci_bar *bar = &device->bars[index];

	VFIO_ASSERT_LT(index, PCI_STD_NUM_BARS);
	VFIO_ASSERT_NOT_NULL(bar->vaddr);

	VFIO_ASSERT_EQ(munmap(bar->vaddr, bar->info.size), 0);
	bar->vaddr = NULL;
}

static void vfio_pci_bar_unmap_all(struct vfio_pci_device *device)
{
	int i;

	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
		if (device->bars[i].vaddr)
			vfio_pci_bar_unmap(device, i);
	}
}

void vfio_pci_config_access(struct vfio_pci_device *device, bool write,
			    size_t config, size_t size, void *data)
{
	struct vfio_region_info *config_space = &device->config_space;
	int ret;

	if (write)
		ret = pwrite(device->fd, data, size, config_space->offset + config);
	else
		ret = pread(device->fd, data, size, config_space->offset + config);

	VFIO_ASSERT_EQ(ret, size, "Failed to %s PCI config space: 0x%lx\n",
		       write ? "write to" : "read from", config);
}

int __vfio_pci_device_reset(struct vfio_pci_device *device)
{
	if (ioctl(device->fd, VFIO_DEVICE_RESET, NULL))
		return -errno;

	return 0;
}

void vfio_pci_device_reset(struct vfio_pci_device *device)
{
	int retries = 20;
	int r;

	do {
		r = __vfio_pci_device_reset(device);
		if (r == -EAGAIN)
			usleep(10000);
	} while (r == -EAGAIN && retries-- > 0);

	VFIO_ASSERT_EQ(r, 0, "ioctl(device->fd, VFIO_DEVICE_RESET) failed\n");
}

void vfio_pci_group_setup(struct vfio_pci_device *device, const char *bdf)
{
	struct vfio_group_status group_status = {
		.argsz = sizeof(group_status),
	};
	char group_path[32];
	int group;

	group = sysfs_iommu_group_get(bdf);
	snprintf_assert(group_path, sizeof(group_path), "/dev/vfio/%d", group);

	device->group_fd = open(group_path, O_RDWR);
	VFIO_ASSERT_GE(device->group_fd, 0, "open(%s) failed\n", group_path);

	ioctl_assert(device->group_fd, VFIO_GROUP_GET_STATUS, &group_status);
	VFIO_ASSERT_TRUE(group_status.flags & VFIO_GROUP_FLAGS_VIABLE);

	ioctl_assert(device->group_fd, VFIO_GROUP_SET_CONTAINER, &device->iommu->container_fd);
}

void __vfio_pci_group_get_device_fd(struct vfio_pci_device *device,
				    const char *bdf, const char *vf_token)
{
	char arg[64];

	/*
	 * If a vf_token exists, argument to VFIO_GROUP_GET_DEVICE_FD
	 * will be in the form of the following example:
	 * "0000:04:10.0 vf_token=bd8d9d2b-5a5f-4f5a-a211-f591514ba1f3"
	 */
	if (vf_token)
		snprintf_assert(arg, ARRAY_SIZE(arg), "%s vf_token=%s", bdf, vf_token);
	else
		snprintf_assert(arg, ARRAY_SIZE(arg), "%s", bdf);

	device->fd = ioctl(device->group_fd, VFIO_GROUP_GET_DEVICE_FD, arg);
}

static void vfio_pci_group_get_device_fd(struct vfio_pci_device *device,
					 const char *bdf, const char *vf_token)
{
	__vfio_pci_group_get_device_fd(device, bdf, vf_token);
	VFIO_ASSERT_GE(device->fd, 0);
}

void vfio_container_set_iommu(struct vfio_pci_device *device)
{
	struct iommu *iommu = device->iommu;
	unsigned long iommu_type = iommu->mode->iommu_type;
	int ret;

	ret = ioctl(iommu->container_fd, VFIO_CHECK_EXTENSION, iommu_type);
	VFIO_ASSERT_GT(ret, 0, "VFIO IOMMU type %lu not supported\n", iommu_type);

	/*
	 * Allow multiple threads to race to set the IOMMU type on the
	 * container. The first will succeed and the rest should fail
	 * because the IOMMU type is already set.
	 */
	(void)ioctl(iommu->container_fd, VFIO_SET_IOMMU, (void *)iommu_type);
}

static void vfio_pci_container_setup(struct vfio_pci_device *device,
				     const char *bdf, const char *vf_token)
{
	vfio_pci_group_setup(device, bdf);
	vfio_container_set_iommu(device);
	vfio_pci_group_get_device_fd(device, bdf, vf_token);
}

static void vfio_pci_device_setup(struct vfio_pci_device *device)
{
	int i;

	device->info.argsz = sizeof(device->info);
	ioctl_assert(device->fd, VFIO_DEVICE_GET_INFO, &device->info);

	vfio_pci_region_get(device, VFIO_PCI_CONFIG_REGION_INDEX, &device->config_space);

	/* Sanity check VFIO does not advertise mmap for config space */
	VFIO_ASSERT_TRUE(!(device->config_space.flags & VFIO_REGION_INFO_FLAG_MMAP),
			 "PCI config space should not support mmap()\n");

	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
		struct vfio_pci_bar *bar = device->bars + i;

		vfio_pci_region_get(device, i, &bar->info);
		if (bar->info.flags & VFIO_REGION_INFO_FLAG_MMAP)
			vfio_pci_bar_map(device, i);
	}

	vfio_pci_irq_get(device, VFIO_PCI_MSI_IRQ_INDEX, &device->msi_info);
	vfio_pci_irq_get(device, VFIO_PCI_MSIX_IRQ_INDEX, &device->msix_info);

	for (i = 0; i < ARRAY_SIZE(device->msi_eventfds); i++)
		device->msi_eventfds[i] = -1;
}

const char *vfio_pci_get_cdev_path(const char *bdf)
{
	char dir_path[PATH_MAX];
	struct dirent *entry;
	char *cdev_path;
	DIR *dir;

	cdev_path = calloc_assert(PATH_MAX, 1);

	snprintf_assert(dir_path, sizeof(dir_path), "/sys/bus/pci/devices/%s/vfio-dev/", bdf);

	dir = opendir(dir_path);
	VFIO_ASSERT_NOT_NULL(dir, "Failed to open directory %s\n", dir_path);

	while ((entry = readdir(dir)) != NULL) {
		/* Find the file that starts with "vfio" */
		if (strncmp("vfio", entry->d_name, 4))
			continue;

		snprintf_assert(cdev_path, PATH_MAX, "/dev/vfio/devices/%s", entry->d_name);
		break;
	}

	VFIO_ASSERT_NE(cdev_path[0], 0, "Failed to find vfio cdev file.\n");
	VFIO_ASSERT_EQ(closedir(dir), 0);

	return cdev_path;
}

int __vfio_device_bind_iommufd(int device_fd, int iommufd, const char *vf_token)
{
	struct vfio_device_bind_iommufd args = {
		.argsz = sizeof(args),
		.iommufd = iommufd,
	};
	uuid_t token_uuid;

	if (vf_token) {
		VFIO_ASSERT_EQ(uuid_parse(vf_token, token_uuid), 0);
		args.flags |= VFIO_DEVICE_BIND_FLAG_TOKEN;
		args.token_uuid_ptr = (u64)token_uuid;
	}

	if (ioctl(device_fd, VFIO_DEVICE_BIND_IOMMUFD, &args))
		return -errno;

	return 0;
}

static void vfio_device_bind_iommufd(int device_fd, int iommufd,
				     const char *vf_token)
{
	int ret = __vfio_device_bind_iommufd(device_fd, iommufd, vf_token);

	VFIO_ASSERT_EQ(ret, 0, "Failed VFIO_DEVICE_BIND_IOMMUFD ioctl\n");
}

static void vfio_device_attach_iommufd_pt(int device_fd, u32 pt_id)
{
	struct vfio_device_attach_iommufd_pt args = {
		.argsz = sizeof(args),
		.pt_id = pt_id,
	};

	ioctl_assert(device_fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &args);
}

void vfio_pci_cdev_open(struct vfio_pci_device *device, const char *bdf)
{
	const char *cdev_path = vfio_pci_get_cdev_path(bdf);

	device->fd = open(cdev_path, O_RDWR);
	VFIO_ASSERT_GE(device->fd, 0);
	free((void *)cdev_path);
}

static void vfio_pci_iommufd_setup(struct vfio_pci_device *device,
				   const char *bdf, const char *vf_token)
{
	vfio_pci_cdev_open(device, bdf);
	vfio_device_bind_iommufd(device->fd, device->iommu->iommufd, vf_token);
	vfio_device_attach_iommufd_pt(device->fd, device->iommu->ioas_id);
}

struct vfio_pci_device *vfio_pci_device_alloc(const char *bdf, struct iommu *iommu)
{
	struct vfio_pci_device *device;

	device = calloc_assert(1, sizeof(*device));

	VFIO_ASSERT_NOT_NULL(iommu);
	device->iommu = iommu;
	device->bdf = bdf;

	return device;
}

void vfio_pci_device_free(struct vfio_pci_device *device)
{
	free(device);
}

struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iommu)
{
	struct vfio_pci_device *device;

	device = vfio_pci_device_alloc(bdf, iommu);

	if (iommu->mode->container_path)
		vfio_pci_container_setup(device, bdf, NULL);
	else
		vfio_pci_iommufd_setup(device, bdf, NULL);

	vfio_pci_device_setup(device);
	vfio_pci_driver_probe(device);

	return device;
}

void vfio_pci_device_cleanup(struct vfio_pci_device *device)
{
	int i;

	if (device->driver.initialized)
		vfio_pci_driver_remove(device);

	vfio_pci_bar_unmap_all(device);

	VFIO_ASSERT_EQ(close(device->fd), 0);

	for (i = 0; i < ARRAY_SIZE(device->msi_eventfds); i++) {
		if (device->msi_eventfds[i] < 0)
			continue;

		VFIO_ASSERT_EQ(close(device->msi_eventfds[i]), 0);
	}

	if (device->group_fd)
		VFIO_ASSERT_EQ(close(device->group_fd), 0);

	vfio_pci_device_free(device);
}
