/* Copyright (c) 2016 Google Inc.
 *
 * See LICENSE for details.
 *
 * Helper functions for virtual machines */

#include <errno.h>
#include <stdlib.h>
#include <parlib/bitmask.h>
#include <parlib/uthread.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/queue.h>
#include <vmm/vmm.h>
#include <vmm/vthread.h>

static struct vmm_thread_tq parked_vths = TAILQ_HEAD_INITIALIZER(parked_vths);
static struct spin_pdr_lock park_lock = SPINPDR_INITIALIZER;

static void *pages(size_t count)
{
	void *v;
	unsigned long flags = MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE;

	return mmap(0, count * PGSIZE, PROT_READ | PROT_WRITE, flags, -1, 0);
}

static void vmsetup(void *arg)
{
	struct virtual_machine *vm = (struct virtual_machine *)arg;

	setup_paging(vm);
	vm->nr_gpcs = 0;
	vm->__gths = NULL;
	vm->gth_array_elem = 0;
	uthread_mcp_init();
}

void gpci_init(struct vmm_gpcore_init *gpci)
{
	uint8_t *p;

	/* Technically, we don't need these pages for the all guests. Currently,
	 * the kernel requires them. */
	p = pages(3);
	if (!p)
		panic("Can't allocate 3 pages for guest: %r");
	gpci->posted_irq_desc = &p[0];
	gpci->vapic_addr = &p[4096];
	gpci->apic_addr = &p[8192];
	/* TODO: once we are making these GPCs at the same time as vthreads, we
	 * should set fsbase == the TLS desc of the vthread (if any). */
	gpci->fsbase = 0;
	gpci->gsbase = 0;
}

/* Helper, grows the array of guest_threads in vm.  Concurrent readers
 * (gpcid_to_gth()) need to use a seq-lock-style of concurrency.  They could
 * read the old array even after we free it.
 *
 * Unlike in the kernel, concurrent readers in userspace shouldn't even read
 * freed memory.  Electric fence could catch that fault.  Until we have a decent
 * userspace RCU, we can avoid these faults WHP by just sleeping. */
static void __grow_gth_array(struct virtual_machine *vm,
                             unsigned int new_nr_gths)
{
	struct guest_thread **new_array, **old_array;
	size_t new_nr_elem;

	if (new_nr_gths <= vm->gth_array_elem)
		return;
	/* TODO: (RCU) we could defer the free */
	old_array = vm->__gths;
	new_nr_elem = MAX(vm->gth_array_elem * 2, new_nr_gths);
	new_array = calloc(new_nr_elem, sizeof(void*));
	assert(new_array);
	memcpy(new_array, vm->__gths, sizeof(void*) * vm->nr_gpcs);
	wmb();	/* all elements written before changing pointer */
	vm->__gths = new_array;
	wmb();	/* ptr written before potentially clobbering freed memory. */
	uthread_usleep(1000);	/* hack for electric fence */
	free(old_array);
}

void __add_gth_to_vm(struct virtual_machine *vm, struct guest_thread *gth)
{
	__grow_gth_array(vm, vm->nr_gpcs + 1);
	vm->__gths[vm->nr_gpcs] = gth;
	wmb();	/* concurrent readers will check nr_gpcs first */
	vm->nr_gpcs++;
}

/* If we fully destroy these uthreads, we'll need to call uthread_cleanup() */
void __vthread_exited(struct vthread *vth)
{
	struct virtual_machine *vm = vth_to_vm(vth);

	spin_pdr_lock(&park_lock);
	TAILQ_INSERT_HEAD(&parked_vths, (struct vmm_thread*)vth, tq_next);
	spin_pdr_unlock(&park_lock);
}

/* The tricky part is that we need to reinit the threads */
static struct vthread *get_parked_vth(struct virtual_machine *vm)
{
	struct vmm_thread *vmth;
	struct guest_thread *gth;
	struct ctlr_thread *cth;
	/* These are from create_guest_thread() */
	struct uth_thread_attr gth_attr = {.want_tls = FALSE};
	struct uth_thread_attr cth_attr = {.want_tls = TRUE};

	spin_pdr_lock(&park_lock);
	vmth = TAILQ_FIRST(&parked_vths);
	if (!vmth) {
		spin_pdr_unlock(&park_lock);
		return NULL;
	}
	TAILQ_REMOVE(&parked_vths, vmth, tq_next);
	spin_pdr_unlock(&park_lock);

	gth = (struct guest_thread*)vmth;
	cth = gth->buddy;
	uthread_init((struct uthread*)gth, &gth_attr);
	uthread_init((struct uthread*)cth, &cth_attr);
	return (struct vthread*)gth;
}

struct vthread *vthread_alloc(struct virtual_machine *vm,
                              struct vmm_gpcore_init *gpci)
{
	static parlib_once_t once = PARLIB_ONCE_INIT;
	struct guest_thread *gth;
	struct vthread *vth;
	int ret;

	parlib_run_once(&once, vmsetup, vm);

	vth = get_parked_vth(vm);
	if (vth)
		return vth;
	uth_mutex_lock(&vm->mtx);
	ret = syscall(SYS_vmm_add_gpcs, 1, gpci);
	assert(ret == 1);
	gth = create_guest_thread(vm, vm->nr_gpcs, gpci);
	assert(gth);
	__add_gth_to_vm(vm, gth);
	uth_mutex_unlock(&vm->mtx);
	/* TODO: somewhat arch specific */
	gth_to_vmtf(gth)->tf_cr3 = (uintptr_t)vm->root;
	return (struct vthread*)gth;
}

/* TODO: this is arch specific */
void vthread_init_ctx(struct vthread *vth, uintptr_t entry_pt, uintptr_t arg,
                      uintptr_t stacktop)
{
	struct vm_trapframe *vm_tf = vth_to_vmtf(vth);

	vm_tf->tf_rip = entry_pt;
	vm_tf->tf_rdi = arg;
	vm_tf->tf_rsp = stacktop;
}

void vthread_run(struct vthread *vthread)
{
	start_guest_thread((struct guest_thread*)vthread);
}

#define DEFAULT_STACK_SIZE 65536
static uintptr_t alloc_stacktop(struct virtual_machine *vm)
{
	int ret;
	uintptr_t *stack, *tos;

	ret = posix_memalign((void **)&stack, PGSIZE, DEFAULT_STACK_SIZE);
	if (ret)
		return 0;
	add_pte_entries(vm, (uintptr_t)stack,
	                (uintptr_t)stack + DEFAULT_STACK_SIZE);
	/* touch the top word on the stack so we don't page fault
	 * on that in the VM. */
	tos = &stack[DEFAULT_STACK_SIZE / sizeof(uint64_t) - 1];
	*tos = 0;
	return (uintptr_t)tos;
}

static uintptr_t vth_get_stack(struct vthread *vth)
{
	struct guest_thread *gth = (struct guest_thread*)vth;
	struct vthread_info *info = (struct vthread_info*)gth->user_data;
	uintptr_t stacktop;

	if (info) {
		assert(info->stacktop);
		return info->stacktop;
	}
	stacktop = alloc_stacktop(vth_to_vm(vth));
	assert(stacktop);
	/* Yes, an evil part of me thought of using the top of the stack for
	 * this struct's storage. */
	gth->user_data = malloc(sizeof(struct vthread_info));
	assert(gth->user_data);
	info = (struct vthread_info*)gth->user_data;
	info->stacktop = stacktop;
	return stacktop;
}

struct vthread *vthread_create(struct virtual_machine *vm, void *entry,
                               void *arg)
{
	struct vthread *vth;
	struct vmm_gpcore_init gpci[1];

	gpci_init(gpci);
	vth = vthread_alloc(vm, gpci);
	if (!vth)
		return NULL;
	vthread_init_ctx(vth, (uintptr_t)entry, (uintptr_t)arg,
			 vth_get_stack(vth));
	vthread_run(vth);
	return vth;
}

void vthread_join(struct vthread *vth, void **retval_loc)
{
	struct ctlr_thread *cth = ((struct guest_thread*)vth)->buddy;

	uthread_join((struct uthread*)cth, retval_loc);
}

long vmcall(unsigned int vmcall_nr, ...)
{
	va_list vl;
	long a0, a1, a2, a3, a4;

	va_start(vl, vmcall_nr);
	a0 = va_arg(vl, long);
	a1 = va_arg(vl, long);
	a2 = va_arg(vl, long);
	a3 = va_arg(vl, long);
	a4 = va_arg(vl, long);
	va_end(vl);
	return raw_vmcall(a0, a1, a2, a3, a4, vmcall_nr);
}

bool vth_handle_vmcall(struct guest_thread *gth, struct vm_trapframe *vm_tf)
{
	switch (vm_tf->tf_rax) {
	case VTH_VMCALL_NULL:
		goto out_ok;
	case VTH_VMCALL_PRINTC:
		fprintf(stdout, "%c", vm_tf->tf_rdi);
		fflush(stdout);
		goto out_ok;
	case VTH_VMCALL_EXIT:
		uth_2ls_thread_exit((void*)vm_tf->tf_rdi);
		assert(0);
	default:
		fprintf(stderr, "Unknown syscall nr %d\n", vm_tf->tf_rax);
		return FALSE;
	}
	assert(0);
out_ok:
	vm_tf->tf_rip += 3;
	return TRUE;
}
