#include "kvm/irq.h"
#include "kvm/virtio.h"
#include "kvm/epoll.h"

#include <linux/kvm.h>
#include <linux/vhost.h>
#include <linux/list.h>

#include <sys/eventfd.h>

static struct kvm__epoll epoll;

static void virtio_vhost_signal_vq(struct kvm *kvm, struct epoll_event *ev)
{
	int r;
	u64 tmp;
	struct virt_queue *queue = ev->data.ptr;

	if (read(queue->irqfd, &tmp, sizeof(tmp)) < 0)
		pr_warning("%s: failed to read eventfd", __func__);

	r = queue->vdev->ops->signal_vq(kvm, queue->vdev, queue->index);
	if (r)
		pr_warning("%s failed to signal virtqueue", __func__);
}

static int virtio_vhost_start_poll(struct kvm *kvm)
{
	if (epoll.fd)
		return 0;

	if (epoll__init(kvm, &epoll, "vhost-irq-worker",
			virtio_vhost_signal_vq))
		return -1;

	return 0;
}

static int virtio_vhost_stop_poll(struct kvm *kvm)
{
	if (epoll.fd)
		epoll__exit(&epoll);
	return 0;
}
base_exit(virtio_vhost_stop_poll);

void virtio_vhost_init(struct kvm *kvm, int vhost_fd)
{
	struct kvm_mem_bank *bank;
	struct vhost_memory *mem;
	int i = 0, r;

	r = virtio_vhost_start_poll(kvm);
	if (r)
		die("Unable to start vhost polling thread\n");

	mem = calloc(1, sizeof(*mem) +
		     kvm->mem_slots * sizeof(struct vhost_memory_region));
	if (mem == NULL)
		die("Failed allocating memory for vhost memory map");

	list_for_each_entry(bank, &kvm->mem_banks, list) {
		mem->regions[i] = (struct vhost_memory_region) {
			.guest_phys_addr = bank->guest_phys_addr,
			.memory_size	 = bank->size,
			.userspace_addr	 = (unsigned long)bank->host_addr,
		};
		i++;
	}
	mem->nregions = i;

	r = ioctl(vhost_fd, VHOST_SET_OWNER);
	if (r != 0)
		die_perror("VHOST_SET_OWNER failed");

	r = ioctl(vhost_fd, VHOST_SET_MEM_TABLE, mem);
	if (r != 0)
		die_perror("VHOST_SET_MEM_TABLE failed");

	free(mem);
}

static int virtio_vhost_get_irqfd(struct virt_queue *queue)
{
	if (!queue->irqfd) {
		queue->irqfd = eventfd(0, 0);
		if (queue->irqfd < 0)
			die_perror("eventfd()");
	}
	return queue->irqfd;
}

void virtio_vhost_set_vring(struct kvm *kvm, int vhost_fd, u32 index,
			    struct virt_queue *queue)
{
	int r;
	struct vhost_vring_addr addr = {
		.index = index,
		.desc_user_addr = (u64)(unsigned long)queue->vring.desc,
		.avail_user_addr = (u64)(unsigned long)queue->vring.avail,
		.used_user_addr = (u64)(unsigned long)queue->vring.used,
	};
	struct vhost_vring_state state = { .index = index };
	struct vhost_vring_file file = {
		.index	= index,
		.fd	= virtio_vhost_get_irqfd(queue),
	};
	struct epoll_event event = {
		.events = EPOLLIN,
		.data.ptr = queue,
	};

	queue->index = index;

	if (queue->endian != VIRTIO_ENDIAN_HOST)
		die("VHOST requires the same endianness in guest and host");

	state.num = queue->vring.num;
	r = ioctl(vhost_fd, VHOST_SET_VRING_NUM, &state);
	if (r < 0)
		die_perror("VHOST_SET_VRING_NUM failed");

	state.num = 0;
	r = ioctl(vhost_fd, VHOST_SET_VRING_BASE, &state);
	if (r < 0)
		die_perror("VHOST_SET_VRING_BASE failed");

	r = ioctl(vhost_fd, VHOST_SET_VRING_ADDR, &addr);
	if (r < 0)
		die_perror("VHOST_SET_VRING_ADDR failed");

	r = ioctl(vhost_fd, VHOST_SET_VRING_CALL, &file);
	if (r < 0)
		die_perror("VHOST_SET_VRING_CALL failed");

	r = epoll_ctl(epoll.fd, EPOLL_CTL_ADD, file.fd, &event);
	if (r < 0)
		die_perror("EPOLL_CTL_ADD vhost call fd");
}

void virtio_vhost_set_vring_kick(struct kvm *kvm, int vhost_fd,
				 u32 index, int event_fd)
{
	int r;
	struct vhost_vring_file file = {
		.index	= index,
		.fd	= event_fd,
	};

	r = ioctl(vhost_fd, VHOST_SET_VRING_KICK, &file);
	if (r < 0)
		die_perror("VHOST_SET_VRING_KICK failed");
}

void virtio_vhost_set_vring_irqfd(struct kvm *kvm, u32 gsi,
				  struct virt_queue *queue)
{
	int r;
	int fd = virtio_vhost_get_irqfd(queue);

	if (queue->gsi)
		irq__del_irqfd(kvm, queue->gsi, fd);
	else
		/* Disconnect user polling thread */
		epoll_ctl(epoll.fd, EPOLL_CTL_DEL, fd, NULL);

	/* Connect the direct IRQFD route */
	r = irq__add_irqfd(kvm, gsi, fd, -1);
	if (r < 0)
		die_perror("KVM_IRQFD failed");

	queue->gsi = gsi;
}

void virtio_vhost_reset_vring(struct kvm *kvm, int vhost_fd, u32 index,
			      struct virt_queue *queue)

{
	struct vhost_vring_file file = {
		.index	= index,
		.fd	= -1,
	};

	if (!queue->irqfd)
		return;

	if (queue->gsi) {
		irq__del_irqfd(kvm, queue->gsi, queue->irqfd);
		queue->gsi = 0;
	}

	epoll_ctl(epoll.fd, EPOLL_CTL_DEL, queue->irqfd, NULL);

	if (ioctl(vhost_fd, VHOST_SET_VRING_CALL, &file))
		perror("SET_VRING_CALL");
	close(queue->irqfd);
	queue->irqfd = 0;
}

int virtio_vhost_set_features(int vhost_fd, u64 features)
{
	/*
	 * vhost interprets VIRTIO_F_ACCESS_PLATFORM as meaning there is an
	 * iotlb. Since this is not the case for kvmtool, mask it.
	 */
	u64 masked_feat = features & ~(1ULL << VIRTIO_F_ACCESS_PLATFORM);

	return ioctl(vhost_fd, VHOST_SET_FEATURES, &masked_feat);
}
