/*
 * Framework for testing nested virtualization
 */

#include "svm.h"
#include "libcflat.h"
#include "processor.h"
#include "desc.h"
#include "msr.h"
#include "vm.h"
#include "fwcfg.h"
#include "smp.h"
#include "alloc_page.h"
#include "isr.h"
#include "apic.h"

/* for the nested page table*/
u64 *pml4e;

struct vmcb *vmcb;

u64 *npt_get_pte(u64 address)
{
	return get_pte(npt_get_pml4e(), (void*)address);
}

u64 *npt_get_pde(u64 address)
{
	struct pte_search search;
	search = find_pte_level(npt_get_pml4e(), (void*)address, 2);
	return search.pte;
}

u64 *npt_get_pdpe(u64 address)
{
	struct pte_search search;
	search = find_pte_level(npt_get_pml4e(), (void*)address, 3);
	return search.pte;
}

u64 *npt_get_pml4e(void)
{
	return pml4e;
}

bool smp_supported(void)
{
	return cpu_count() > 1;
}

bool default_supported(void)
{
	return true;
}

bool vgif_supported(void)
{
	return this_cpu_has(X86_FEATURE_VGIF);
}

bool lbrv_supported(void)
{
	return this_cpu_has(X86_FEATURE_LBRV);
}

bool tsc_scale_supported(void)
{
	return this_cpu_has(X86_FEATURE_TSCRATEMSR);
}

bool pause_filter_supported(void)
{
	return this_cpu_has(X86_FEATURE_PAUSEFILTER);
}

bool pause_threshold_supported(void)
{
	return this_cpu_has(X86_FEATURE_PFTHRESHOLD);
}


void default_prepare(struct svm_test *test)
{
	vmcb_ident(vmcb);
}

void default_prepare_gif_clear(struct svm_test *test)
{
}

bool default_finished(struct svm_test *test)
{
	return true; /* one vmexit */
}

bool npt_supported(void)
{
	return this_cpu_has(X86_FEATURE_NPT);
}

bool vnmi_supported(void)
{
       return this_cpu_has(X86_FEATURE_VNMI);
}

int get_test_stage(struct svm_test *test)
{
	barrier();
	return test->scratch;
}

void set_test_stage(struct svm_test *test, int s)
{
	barrier();
	test->scratch = s;
	barrier();
}

void inc_test_stage(struct svm_test *test)
{
	barrier();
	test->scratch++;
	barrier();
}

static void vmcb_set_seg(struct vmcb_seg *seg, u16 selector,
			 u64 base, u32 limit, u32 attr)
{
	seg->selector = selector;
	seg->attrib = attr;
	seg->limit = limit;
	seg->base = base;
}

inline void vmmcall(void)
{
	asm volatile ("vmmcall" : : : "memory");
}

static test_guest_func guest_main;

void test_set_guest(test_guest_func func)
{
	guest_main = func;
}

static void test_thunk(struct svm_test *test)
{
	guest_main(test);
	vmmcall();
}

u8 *io_bitmap;
u8 io_bitmap_area[16384];

u8 *msr_bitmap;
u8 msr_bitmap_area[MSR_BITMAP_SIZE + PAGE_SIZE];

void vmcb_ident(struct vmcb *vmcb)
{
	u64 vmcb_phys = virt_to_phys(vmcb);
	struct vmcb_save_area *save = &vmcb->save;
	struct vmcb_control_area *ctrl = &vmcb->control;
	u32 data_seg_attr = 3 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK
		| SVM_SELECTOR_DB_MASK | SVM_SELECTOR_G_MASK;
	u32 code_seg_attr = 9 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK
		| SVM_SELECTOR_L_MASK | SVM_SELECTOR_G_MASK;
	struct descriptor_table_ptr desc_table_ptr;

	memset(vmcb, 0, sizeof(*vmcb));
	asm volatile ("vmsave %0" : : "a"(vmcb_phys) : "memory");
	vmcb_set_seg(&save->es, read_es(), 0, -1U, data_seg_attr);
	vmcb_set_seg(&save->cs, read_cs(), 0, -1U, code_seg_attr);
	vmcb_set_seg(&save->ss, read_ss(), 0, -1U, data_seg_attr);
	vmcb_set_seg(&save->ds, read_ds(), 0, -1U, data_seg_attr);
	sgdt(&desc_table_ptr);
	vmcb_set_seg(&save->gdtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0);
	sidt(&desc_table_ptr);
	vmcb_set_seg(&save->idtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0);
	ctrl->asid = 1;
	save->cpl = 0;
	save->efer = rdmsr(MSR_EFER);
	save->cr4 = read_cr4();
	save->cr3 = read_cr3();
	save->cr0 = read_cr0();
	save->dr7 = read_dr7();
	save->dr6 = read_dr6();
	save->cr2 = read_cr2();
	save->g_pat = rdmsr(MSR_IA32_CR_PAT);
	save->dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
	ctrl->intercept = (1ULL << INTERCEPT_VMRUN) |
		(1ULL << INTERCEPT_VMMCALL) |
		(1ULL << INTERCEPT_SHUTDOWN);
	ctrl->iopm_base_pa = virt_to_phys(io_bitmap);
	ctrl->msrpm_base_pa = virt_to_phys(msr_bitmap);

	if (npt_supported()) {
		ctrl->nested_ctl = 1;
		ctrl->nested_cr3 = (u64)pml4e;
		ctrl->tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;
	}
}

struct regs regs;

struct regs get_regs(void)
{
	return regs;
}

// rax handled specially below


struct svm_test *v2_test;


u64 guest_stack[10000];

void svm_setup_vmrun(u64 rip)
{
	vmcb->save.rip = (ulong)rip;
	vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack));
}

int __svm_vmrun(u64 rip)
{
	svm_setup_vmrun(rip);
	regs.rdi = (ulong)v2_test;

	asm volatile (
		      ASM_PRE_VMRUN_CMD
		      "vmrun %%rax\n\t"               \
		      ASM_POST_VMRUN_CMD
		      :
		      : "a" (virt_to_phys(vmcb))
		      : "memory", "r15");

	return (vmcb->control.exit_code);
}

int svm_vmrun(void)
{
	return __svm_vmrun((u64)test_thunk);
}

extern u8 vmrun_rip;

static noinline void test_run(struct svm_test *test)
{
	u64 vmcb_phys = virt_to_phys(vmcb);

	cli();
	vmcb_ident(vmcb);

	test->prepare(test);
	guest_main = test->guest_func;
	vmcb->save.rip = (ulong)test_thunk;
	vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack));
	regs.rdi = (ulong)test;
	do {
		struct svm_test *the_test = test;
		u64 the_vmcb = vmcb_phys;
		asm volatile (
			      "clgi;\n\t" // semi-colon needed for LLVM compatibility
			      "sti \n\t"
			      "call *%c[PREPARE_GIF_CLEAR](%[test]) \n \t"
			      "mov %[vmcb_phys], %%rax \n\t"
			      ASM_PRE_VMRUN_CMD
			      ".global vmrun_rip\n\t"		\
			      "vmrun_rip: vmrun %%rax\n\t"    \
			      ASM_POST_VMRUN_CMD
			      "cli \n\t"
			      "stgi"
			      : // inputs clobbered by the guest:
				"=D" (the_test),            // first argument register
				"=b" (the_vmcb)             // callee save register!
			      : [test] "0" (the_test),
				[vmcb_phys] "1"(the_vmcb),
				[PREPARE_GIF_CLEAR] "i" (offsetof(struct svm_test, prepare_gif_clear))
			      : "rax", "rcx", "rdx", "rsi",
				"r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15",
				"memory");
		++test->exits;
	} while (!test->finished(test));
	sti();

	report(test->succeeded(test), "%s", test->name);

	if (test->on_vcpu)
		test->on_vcpu_done = true;
}

static void set_additional_vcpu_msr(void *msr_efer)
{
	void *hsave = alloc_page();

	wrmsr(MSR_VM_HSAVE_PA, virt_to_phys(hsave));
	wrmsr(MSR_EFER, (ulong)msr_efer | EFER_SVME);
}

static void setup_npt(void)
{
	u64 size = fwcfg_get_u64(FW_CFG_RAM_SIZE);

	/* Ensure all <4gb is mapped, e.g. if there's no RAM above 4gb. */
	if (size < BIT_ULL(32))
		size = BIT_ULL(32);

	pml4e = alloc_page();

	/* NPT accesses are treated as "user" accesses. */
	__setup_mmu_range(pml4e, 0, size, X86_MMU_MAP_USER);
}

static void setup_svm(void)
{
	void *hsave = alloc_page();
	int i;

	wrmsr(MSR_VM_HSAVE_PA, virt_to_phys(hsave));
	wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SVME);

	io_bitmap = (void *) ALIGN((ulong)io_bitmap_area, PAGE_SIZE);

	msr_bitmap = (void *) ALIGN((ulong)msr_bitmap_area, PAGE_SIZE);

	if (!npt_supported())
		return;

	for (i = 1; i < cpu_count(); i++)
		on_cpu(i, (void *)set_additional_vcpu_msr, (void *)rdmsr(MSR_EFER));

	printf("NPT detected - running all tests with NPT enabled\n");

	/*
	 * Nested paging supported - Build a nested page table
	 * Build the page-table bottom-up and map everything with 4k
	 * pages to get enough granularity for the NPT unit-tests.
	 */

	setup_npt();
}

int matched;

static bool
test_wanted(const char *name, char *filters[], int filter_count)
{
	int i;
	bool positive = false;
	bool match = false;
	char clean_name[strlen(name) + 1];
	char *c;
	const char *n;

	/* Replace spaces with underscores. */
	n = name;
	c = &clean_name[0];
	do *c++ = (*n == ' ') ? '_' : *n;
	while (*n++);

	for (i = 0; i < filter_count; i++) {
		const char *filter = filters[i];

		if (filter[0] == '-') {
			if (simple_glob(clean_name, filter + 1))
				return false;
		} else {
			positive = true;
			match |= simple_glob(clean_name, filter);
		}
	}

	if (!positive || match) {
		matched++;
		return true;
	} else {
		return false;
	}
}

int run_svm_tests(int ac, char **av, struct svm_test *svm_tests)
{
	int i = 0;

	ac--;
	av++;

	if (!this_cpu_has(X86_FEATURE_SVM)) {
		printf("SVM not available\n");
		return report_summary();
	}

	setup_svm();

	vmcb = alloc_page();

	for (; svm_tests[i].name != NULL; i++) {
		if (!test_wanted(svm_tests[i].name, av, ac))
			continue;
		if (svm_tests[i].supported && !svm_tests[i].supported())
			continue;
		if (svm_tests[i].v2 == NULL) {
			if (svm_tests[i].on_vcpu) {
				if (cpu_count() <= svm_tests[i].on_vcpu)
					continue;
				on_cpu_async(svm_tests[i].on_vcpu, (void *)test_run, &svm_tests[i]);
				while (!svm_tests[i].on_vcpu_done)
					cpu_relax();
			}
			else
				test_run(&svm_tests[i]);
		} else {
			vmcb_ident(vmcb);
			v2_test = &(svm_tests[i]);
			svm_tests[i].v2();
		}
	}

	if (!matched)
		report(matched, "command line didn't match any tests!");

	return report_summary();
}
