// SPDX-License-Identifier: MIT License
/*
 * hypervisor.c
 *
 * Communication to/from hypervisor.
 *
 * Copyright (c) 2002-2003, K A Fraser
 * Copyright (c) 2005, Grzegorz Milos, gm281@cam.ac.uk,Intel Research Cambridge
 * Copyright (c) 2020, EPAM Systems Inc.
 */
#include <cpu_func.h>
#include <log.h>
#include <memalign.h>

#include <asm/io.h>
#include <asm/armv8/mmu.h>
#include <asm/xen/system.h>

#include <linux/bug.h>

#include <xen/hvm.h>
#include <xen/events.h>
#include <xen/gnttab.h>
#include <xen/xenbus.h>
#include <xen/interface/memory.h>

#define active_evtchns(cpu, sh, idx)	\
	((sh)->evtchn_pending[idx] &	\
	 ~(sh)->evtchn_mask[idx])

int in_callback;

/*
 * Shared page for communicating with the hypervisor.
 * Events flags go here, for example.
 */
struct shared_info *HYPERVISOR_shared_info;

static const char *param_name(int op)
{
#define PARAM(x)[HVM_PARAM_##x] = #x
	static const char *const names[] = {
		PARAM(CALLBACK_IRQ),
		PARAM(STORE_PFN),
		PARAM(STORE_EVTCHN),
		PARAM(PAE_ENABLED),
		PARAM(IOREQ_PFN),
		PARAM(VPT_ALIGN),
		PARAM(CONSOLE_PFN),
		PARAM(CONSOLE_EVTCHN),
	};
#undef PARAM

	if (op >= ARRAY_SIZE(names))
		return "unknown";

	if (!names[op])
		return "reserved";

	return names[op];
}

/**
 * hvm_get_parameter_maintain_dcache - function to obtain a HVM
 * parameter value.
 * @idx: HVM parameter index
 * @value: Value to fill in
 *
 * According to Xen on ARM ABI (xen/include/public/arch-arm.h):
 * all memory which is shared with other entities in the system
 * (including the hypervisor and other guests) must reside in memory
 * which is mapped as Normal Inner Write-Back Outer Write-Back
 * Inner-Shareable.
 *
 * Thus, page attributes must be equally set for all the entities
 * working with that page.
 *
 * Before MMU setup the data cache is turned off, so it means that
 * manual data cache maintenance is required, because of the
 * difference of page attributes.
 */
int hvm_get_parameter_maintain_dcache(int idx, uint64_t *value)
{
	struct xen_hvm_param xhv;
	int ret;

	invalidate_dcache_range((unsigned long)&xhv,
				(unsigned long)&xhv + sizeof(xhv));
	xhv.domid = DOMID_SELF;
	xhv.index = idx;
	invalidate_dcache_range((unsigned long)&xhv,
				(unsigned long)&xhv + sizeof(xhv));

	ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
	if (ret < 0) {
		pr_err("Cannot get hvm parameter %s (%d): %d!\n",
			   param_name(idx), idx, ret);
		BUG();
	}
	invalidate_dcache_range((unsigned long)&xhv,
				(unsigned long)&xhv + sizeof(xhv));

	*value = xhv.value;

	return ret;
}

int hvm_get_parameter(int idx, uint64_t *value)
{
	struct xen_hvm_param xhv;
	int ret;

	xhv.domid = DOMID_SELF;
	xhv.index = idx;
	ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
	if (ret < 0) {
		pr_err("Cannot get hvm parameter %s (%d): %d!\n",
			   param_name(idx), idx, ret);
		BUG();
	}

	*value = xhv.value;

	return ret;
}

struct shared_info *map_shared_info(void *p)
{
	struct xen_add_to_physmap xatp;

	HYPERVISOR_shared_info = (struct shared_info *)memalign(PAGE_SIZE,
								PAGE_SIZE);
	if (!HYPERVISOR_shared_info)
		BUG();

	xatp.domid = DOMID_SELF;
	xatp.idx = 0;
	xatp.space = XENMAPSPACE_shared_info;
	xatp.gpfn = virt_to_pfn(HYPERVISOR_shared_info);
	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) != 0)
		BUG();

	return HYPERVISOR_shared_info;
}

void unmap_shared_info(void)
{
	xen_pfn_t shared_info_pfn = virt_to_pfn(HYPERVISOR_shared_info);
	struct xen_remove_from_physmap xrfp = {0};
	struct xen_memory_reservation reservation = {0};
	xen_ulong_t nr_exts = 1;

	xrfp.domid = DOMID_SELF;
	xrfp.gpfn = shared_info_pfn;
	if (HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrfp) != 0)
		panic("Failed to unmap HYPERVISOR_shared_info\n");

	/*
	 * After removing from physmap there will be a hole in address space on
	 * HYPERVISOR_shared_info address, so to free memory allocated with
	 * memalign and prevent exceptions during access to this page we need to
	 * fill this 4KB hole with XENMEM_populate_physmap before jumping to Linux.
	 */
	reservation.domid = DOMID_SELF;
	reservation.extent_order = 0;
	reservation.address_bits = 0;
	set_xen_guest_handle(reservation.extent_start, &shared_info_pfn);
	reservation.nr_extents = nr_exts;
	if (HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation) != nr_exts)
		panic("Failed to populate memory on HYPERVISOR_shared_info addr\n");

	/* Now we can return this to memory allocator */
	free(HYPERVISOR_shared_info);
}

void do_hypervisor_callback(struct pt_regs *regs)
{
	unsigned long l1, l2, l1i, l2i;
	unsigned int port;
	int cpu = 0;
	struct shared_info *s = HYPERVISOR_shared_info;
	struct vcpu_info *vcpu_info = &s->vcpu_info[cpu];

	in_callback = 1;

	vcpu_info->evtchn_upcall_pending = 0;
	l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);

	while (l1 != 0) {
		l1i = __ffs(l1);
		l1 &= ~(1UL << l1i);

		while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
			l2i = __ffs(l2);
			l2 &= ~(1UL << l2i);

			port = (l1i * (sizeof(unsigned long) * 8)) + l2i;
			do_event(port, regs);
		}
	}

	in_callback = 0;
}

void force_evtchn_callback(void)
{
#ifdef XEN_HAVE_PV_UPCALL_MASK
	int save;
#endif
	struct vcpu_info *vcpu;

	vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()];
#ifdef XEN_HAVE_PV_UPCALL_MASK
	save = vcpu->evtchn_upcall_mask;
#endif

	while (vcpu->evtchn_upcall_pending) {
#ifdef XEN_HAVE_PV_UPCALL_MASK
		vcpu->evtchn_upcall_mask = 1;
#endif
		do_hypervisor_callback(NULL);
#ifdef XEN_HAVE_PV_UPCALL_MASK
		vcpu->evtchn_upcall_mask = save;
#endif
	};
}

void mask_evtchn(uint32_t port)
{
	struct shared_info *s = HYPERVISOR_shared_info;

	synch_set_bit(port, &s->evtchn_mask[0]);
}

void unmask_evtchn(uint32_t port)
{
	struct shared_info *s = HYPERVISOR_shared_info;
	struct vcpu_info *vcpu_info = &s->vcpu_info[smp_processor_id()];

	synch_clear_bit(port, &s->evtchn_mask[0]);

	/*
	 * Just like a real IO-APIC we 'lose the interrupt edge' if the
	 * channel is masked.
	 */
	if (synch_test_bit(port, &s->evtchn_pending[0]) &&
	    !synch_test_and_set_bit(port / (sizeof(unsigned long) * 8),
				    &vcpu_info->evtchn_pending_sel)) {
		vcpu_info->evtchn_upcall_pending = 1;
#ifdef XEN_HAVE_PV_UPCALL_MASK
		if (!vcpu_info->evtchn_upcall_mask)
#endif
			force_evtchn_callback();
	}
}

void clear_evtchn(uint32_t port)
{
	struct shared_info *s = HYPERVISOR_shared_info;

	synch_clear_bit(port, &s->evtchn_pending[0]);
}

int xen_init(void)
{
	int el = current_el();

	debug("%s\n", __func__);

	if (el != 1) {
		puts("XEN:\tnot running from EL1\n");
		return 0;
	}

	map_shared_info(NULL);
	init_events();
	init_xenbus();
	init_gnttab();

	return 0;
}

void xen_fini(void)
{
	debug("%s\n", __func__);

	fini_gnttab();
	fini_xenbus();
	fini_events();
	unmap_shared_info();
}
