// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2018, Google LLC.
 */

#include "linux/bitmap.h"
#include "test_util.h"
#include "kvm_util.h"
#include "pmu.h"
#include "processor.h"
#include "smm.h"
#include "svm_util.h"
#include "sev.h"
#include "vmx.h"

#ifndef NUM_INTERRUPTS
#define NUM_INTERRUPTS 256
#endif

#define KERNEL_CS	0x8
#define KERNEL_DS	0x10
#define KERNEL_TSS	0x18

gva_t exception_handlers;
bool host_cpu_is_amd;
bool host_cpu_is_intel;
bool host_cpu_is_hygon;
bool host_cpu_is_amd_compatible;
bool is_forced_emulation_enabled;
u64 guest_tsc_khz;
struct kvm_mmu guest_mmu;

struct guest_regs guest_regs;

const char *ex_str(int vector)
{
	switch (vector) {
#define VEC_STR(v) case v##_VECTOR: return "#" #v
	case DE_VECTOR: return "no exception";
	case KVM_MAGIC_DE_VECTOR: return "#DE";
	VEC_STR(DB);
	VEC_STR(NMI);
	VEC_STR(BP);
	VEC_STR(OF);
	VEC_STR(BR);
	VEC_STR(UD);
	VEC_STR(NM);
	VEC_STR(DF);
	VEC_STR(TS);
	VEC_STR(NP);
	VEC_STR(SS);
	VEC_STR(GP);
	VEC_STR(PF);
	VEC_STR(MF);
	VEC_STR(AC);
	VEC_STR(MC);
	VEC_STR(XM);
	VEC_STR(VE);
	VEC_STR(CP);
	VEC_STR(HV);
	VEC_STR(VC);
	VEC_STR(SX);
	default: return "#??";
#undef VEC_STR
	}
}

static void regs_dump(FILE *stream, struct kvm_regs *regs, u8 indent)
{
	fprintf(stream, "%*srax: 0x%.16llx rbx: 0x%.16llx "
		"rcx: 0x%.16llx rdx: 0x%.16llx\n",
		indent, "",
		regs->rax, regs->rbx, regs->rcx, regs->rdx);
	fprintf(stream, "%*srsi: 0x%.16llx rdi: 0x%.16llx "
		"rsp: 0x%.16llx rbp: 0x%.16llx\n",
		indent, "",
		regs->rsi, regs->rdi, regs->rsp, regs->rbp);
	fprintf(stream, "%*sr8:  0x%.16llx r9:  0x%.16llx "
		"r10: 0x%.16llx r11: 0x%.16llx\n",
		indent, "",
		regs->r8, regs->r9, regs->r10, regs->r11);
	fprintf(stream, "%*sr12: 0x%.16llx r13: 0x%.16llx "
		"r14: 0x%.16llx r15: 0x%.16llx\n",
		indent, "",
		regs->r12, regs->r13, regs->r14, regs->r15);
	fprintf(stream, "%*srip: 0x%.16llx rfl: 0x%.16llx\n",
		indent, "",
		regs->rip, regs->rflags);
}

static void segment_dump(FILE *stream, struct kvm_segment *segment,
			 u8 indent)
{
	fprintf(stream, "%*sbase: 0x%.16llx limit: 0x%.8x "
		"selector: 0x%.4x type: 0x%.2x\n",
		indent, "", segment->base, segment->limit,
		segment->selector, segment->type);
	fprintf(stream, "%*spresent: 0x%.2x dpl: 0x%.2x "
		"db: 0x%.2x s: 0x%.2x l: 0x%.2x\n",
		indent, "", segment->present, segment->dpl,
		segment->db, segment->s, segment->l);
	fprintf(stream, "%*sg: 0x%.2x avl: 0x%.2x "
		"unusable: 0x%.2x padding: 0x%.2x\n",
		indent, "", segment->g, segment->avl,
		segment->unusable, segment->padding);
}

static void dtable_dump(FILE *stream, struct kvm_dtable *dtable,
			u8 indent)
{
	fprintf(stream, "%*sbase: 0x%.16llx limit: 0x%.4x "
		"padding: 0x%.4x 0x%.4x 0x%.4x\n",
		indent, "", dtable->base, dtable->limit,
		dtable->padding[0], dtable->padding[1], dtable->padding[2]);
}

static void sregs_dump(FILE *stream, struct kvm_sregs *sregs, u8 indent)
{
	unsigned int i;

	fprintf(stream, "%*scs:\n", indent, "");
	segment_dump(stream, &sregs->cs, indent + 2);
	fprintf(stream, "%*sds:\n", indent, "");
	segment_dump(stream, &sregs->ds, indent + 2);
	fprintf(stream, "%*ses:\n", indent, "");
	segment_dump(stream, &sregs->es, indent + 2);
	fprintf(stream, "%*sfs:\n", indent, "");
	segment_dump(stream, &sregs->fs, indent + 2);
	fprintf(stream, "%*sgs:\n", indent, "");
	segment_dump(stream, &sregs->gs, indent + 2);
	fprintf(stream, "%*sss:\n", indent, "");
	segment_dump(stream, &sregs->ss, indent + 2);
	fprintf(stream, "%*str:\n", indent, "");
	segment_dump(stream, &sregs->tr, indent + 2);
	fprintf(stream, "%*sldt:\n", indent, "");
	segment_dump(stream, &sregs->ldt, indent + 2);

	fprintf(stream, "%*sgdt:\n", indent, "");
	dtable_dump(stream, &sregs->gdt, indent + 2);
	fprintf(stream, "%*sidt:\n", indent, "");
	dtable_dump(stream, &sregs->idt, indent + 2);

	fprintf(stream, "%*scr0: 0x%.16llx cr2: 0x%.16llx "
		"cr3: 0x%.16llx cr4: 0x%.16llx\n",
		indent, "",
		sregs->cr0, sregs->cr2, sregs->cr3, sregs->cr4);
	fprintf(stream, "%*scr8: 0x%.16llx efer: 0x%.16llx "
		"apic_base: 0x%.16llx\n",
		indent, "",
		sregs->cr8, sregs->efer, sregs->apic_base);

	fprintf(stream, "%*sinterrupt_bitmap:\n", indent, "");
	for (i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++) {
		fprintf(stream, "%*s%.16llx\n", indent + 2, "",
			sregs->interrupt_bitmap[i]);
	}
}

bool kvm_is_tdp_enabled(void)
{
	if (host_cpu_is_intel)
		return get_kvm_intel_param_bool("ept");
	else
		return get_kvm_amd_param_bool("npt");
}

static void virt_mmu_init(struct kvm_vm *vm, struct kvm_mmu *mmu,
			  struct pte_masks *pte_masks)
{
	/* If needed, create the top-level page table. */
	if (!mmu->pgd_created) {
		mmu->pgd = vm_alloc_page_table(vm);
		mmu->pgd_created = true;
		mmu->arch.pte_masks = *pte_masks;
	}

	TEST_ASSERT(mmu->pgtable_levels == 4 || mmu->pgtable_levels == 5,
		    "Selftests MMU only supports 4-level and 5-level paging, not %u-level paging",
		    mmu->pgtable_levels);
}

void virt_arch_pgd_alloc(struct kvm_vm *vm)
{
	TEST_ASSERT(vm->mode == VM_MODE_PXXVYY_4K,
		    "Unknown or unsupported guest mode: 0x%x", vm->mode);

	struct pte_masks pte_masks = (struct pte_masks){
		.present	=	BIT_ULL(0),
		.writable	=	BIT_ULL(1),
		.user		=	BIT_ULL(2),
		.accessed	=	BIT_ULL(5),
		.dirty		=	BIT_ULL(6),
		.huge		=	BIT_ULL(7),
		.nx		=	BIT_ULL(63),
		.executable	=	0,
		.c		=	vm->arch.c_bit,
		.s		=	vm->arch.s_bit,
	};

	virt_mmu_init(vm, &vm->mmu, &pte_masks);
}

void tdp_mmu_init(struct kvm_vm *vm, int pgtable_levels,
		  struct pte_masks *pte_masks)
{
	TEST_ASSERT(!vm->stage2_mmu.pgtable_levels, "TDP MMU already initialized");

	vm->stage2_mmu.pgtable_levels = pgtable_levels;
	virt_mmu_init(vm, &vm->stage2_mmu, pte_masks);
}

static void *virt_get_pte(struct kvm_vm *vm, struct kvm_mmu *mmu,
			  u64 *parent_pte, gva_t gva, int level)
{
	u64 pt_gpa = PTE_GET_PA(*parent_pte);
	u64 *page_table = addr_gpa2hva(vm, pt_gpa);
	int index = (gva >> PG_LEVEL_SHIFT(level)) & 0x1ffu;

	TEST_ASSERT((*parent_pte == mmu->pgd) || is_present_pte(mmu, parent_pte),
		    "Parent PTE (level %d) not PRESENT for gva: 0x%08lx",
		    level + 1, gva);

	return &page_table[index];
}

static u64 *virt_create_upper_pte(struct kvm_vm *vm,
				  struct kvm_mmu *mmu,
				  u64 *parent_pte,
				  gva_t gva,
				  gpa_t gpa,
				  int current_level,
				  int target_level)
{
	u64 *pte = virt_get_pte(vm, mmu, parent_pte, gva, current_level);

	gpa = vm_untag_gpa(vm, gpa);

	if (!is_present_pte(mmu, pte)) {
		*pte = PTE_PRESENT_MASK(mmu) | PTE_READABLE_MASK(mmu) |
		       PTE_WRITABLE_MASK(mmu) | PTE_EXECUTABLE_MASK(mmu) |
		       PTE_ALWAYS_SET_MASK(mmu);
		if (current_level == target_level)
			*pte |= PTE_HUGE_MASK(mmu) | (gpa & PHYSICAL_PAGE_MASK);
		else
			*pte |= vm_alloc_page_table(vm) & PHYSICAL_PAGE_MASK;
	} else {
		/*
		 * Entry already present.  Assert that the caller doesn't want
		 * a hugepage at this level, and that there isn't a hugepage at
		 * this level.
		 */
		TEST_ASSERT(current_level != target_level,
			    "Cannot create hugepage at level: %u, gva: 0x%lx",
			    current_level, gva);
		TEST_ASSERT(!is_huge_pte(mmu, pte),
			    "Cannot create page table at level: %u, gva: 0x%lx",
			    current_level, gva);
	}
	return pte;
}

void __virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, gva_t gva,
		   gpa_t gpa, int level)
{
	const u64 pg_size = PG_LEVEL_SIZE(level);
	u64 *pte = &mmu->pgd;
	int current_level;

	TEST_ASSERT(vm->mode == VM_MODE_PXXVYY_4K,
		    "Unknown or unsupported guest mode: 0x%x", vm->mode);

	TEST_ASSERT((gva % pg_size) == 0,
		    "Virtual address not aligned,\n"
		    "gva: 0x%lx page size: 0x%lx", gva, pg_size);
	TEST_ASSERT(sparsebit_is_set(vm->vpages_valid, (gva >> vm->page_shift)),
		    "Invalid virtual address, gva: 0x%lx", gva);
	TEST_ASSERT((gpa % pg_size) == 0,
		    "Physical address not aligned,\n"
		    "  gpa: 0x%lx page size: 0x%lx", gpa, pg_size);
	TEST_ASSERT((gpa >> vm->page_shift) <= vm->max_gfn,
		    "Physical address beyond maximum supported,\n"
		    "  gpa: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
		    gpa, vm->max_gfn, vm->page_size);
	TEST_ASSERT(vm_untag_gpa(vm, gpa) == gpa,
		    "Unexpected bits in gpa: %lx", gpa);

	TEST_ASSERT(!PTE_EXECUTABLE_MASK(mmu) || !PTE_NX_MASK(mmu),
		    "X and NX bit masks cannot be used simultaneously");

	/*
	 * Allocate upper level page tables, if not already present.  Return
	 * early if a hugepage was created.
	 */
	for (current_level = mmu->pgtable_levels;
	     current_level > PG_LEVEL_4K;
	     current_level--) {
		pte = virt_create_upper_pte(vm, mmu, pte, gva, gpa,
					    current_level, level);
		if (is_huge_pte(mmu, pte))
			return;
	}

	/* Fill in page table entry. */
	pte = virt_get_pte(vm, mmu, pte, gva, PG_LEVEL_4K);
	TEST_ASSERT(!is_present_pte(mmu, pte),
		    "PTE already present for 4k page at gva: 0x%lx", gva);
	*pte = PTE_PRESENT_MASK(mmu) | PTE_READABLE_MASK(mmu) |
	       PTE_WRITABLE_MASK(mmu) | PTE_EXECUTABLE_MASK(mmu) |
	       PTE_ALWAYS_SET_MASK(mmu) | (gpa & PHYSICAL_PAGE_MASK);

	/*
	 * Neither SEV nor TDX supports shared page tables, so only the final
	 * leaf PTE needs manually set the C/S-bit.
	 */
	if (vm_is_gpa_protected(vm, gpa))
		*pte |= PTE_C_BIT_MASK(mmu);
	else
		*pte |= PTE_S_BIT_MASK(mmu);
}

void virt_arch_pg_map(struct kvm_vm *vm, gva_t gva, gpa_t gpa)
{
	__virt_pg_map(vm, &vm->mmu, gva, gpa, PG_LEVEL_4K);
}

void virt_map_level(struct kvm_vm *vm, gva_t gva, gpa_t gpa,
		    u64 nr_bytes, int level)
{
	u64 pg_size = PG_LEVEL_SIZE(level);
	u64 nr_pages = nr_bytes / pg_size;
	int i;

	TEST_ASSERT(nr_bytes % pg_size == 0,
		    "Region size not aligned: nr_bytes: 0x%lx, page size: 0x%lx",
		    nr_bytes, pg_size);

	for (i = 0; i < nr_pages; i++) {
		__virt_pg_map(vm, &vm->mmu, gva, gpa, level);
		sparsebit_set_num(vm->vpages_mapped, gva >> vm->page_shift,
				  nr_bytes / PAGE_SIZE);

		gva += pg_size;
		gpa += pg_size;
	}
}

static bool vm_is_target_pte(struct kvm_mmu *mmu, u64 *pte,
			     int *level, int current_level)
{
	if (is_huge_pte(mmu, pte)) {
		TEST_ASSERT(*level == PG_LEVEL_NONE ||
			    *level == current_level,
			    "Unexpected hugepage at level %d", current_level);
		*level = current_level;
	}

	return *level == current_level;
}

static u64 *__vm_get_page_table_entry(struct kvm_vm *vm,
				      struct kvm_mmu *mmu,
				      gva_t gva,
				      int *level)
{
	int va_width = 12 + (mmu->pgtable_levels) * 9;
	u64 *pte = &mmu->pgd;
	int current_level;

	TEST_ASSERT(!vm->arch.is_pt_protected,
		    "Walking page tables of protected guests is impossible");

	TEST_ASSERT(*level >= PG_LEVEL_NONE && *level <= mmu->pgtable_levels,
		    "Invalid PG_LEVEL_* '%d'", *level);

	TEST_ASSERT(vm->mode == VM_MODE_PXXVYY_4K,
		    "Unknown or unsupported guest mode: 0x%x", vm->mode);
	TEST_ASSERT(sparsebit_is_set(vm->vpages_valid, (gva >> vm->page_shift)),
		    "Invalid virtual address, gva: 0x%lx", gva);
	/*
	 * Check that the gva is a sign-extended va_width value.
	 */
	TEST_ASSERT(gva == (((s64)gva << (64 - va_width) >> (64 - va_width))),
		    "Canonical check failed.  The virtual address is invalid.");

	for (current_level = mmu->pgtable_levels;
	     current_level > PG_LEVEL_4K;
	     current_level--) {
		pte = virt_get_pte(vm, mmu, pte, gva, current_level);
		if (vm_is_target_pte(mmu, pte, level, current_level))
			return pte;
	}

	return virt_get_pte(vm, mmu, pte, gva, PG_LEVEL_4K);
}

u64 *tdp_get_pte(struct kvm_vm *vm, u64 l2_gpa)
{
	int level = PG_LEVEL_4K;

	return __vm_get_page_table_entry(vm, &vm->stage2_mmu, l2_gpa, &level);
}

u64 *vm_get_pte(struct kvm_vm *vm, gva_t gva)
{
	int level = PG_LEVEL_4K;

	return __vm_get_page_table_entry(vm, &vm->mmu, gva, &level);
}

void virt_arch_dump(FILE *stream, struct kvm_vm *vm, u8 indent)
{
	struct kvm_mmu *mmu = &vm->mmu;
	u64 *pml4e, *pml4e_start;
	u64 *pdpe, *pdpe_start;
	u64 *pde, *pde_start;
	u64 *pte, *pte_start;

	if (!mmu->pgd_created)
		return;

	fprintf(stream, "%*s                                          "
		"                no\n", indent, "");
	fprintf(stream, "%*s      index hvaddr         gpaddr         "
		"addr         w exec dirty\n",
		indent, "");
	pml4e_start = (u64 *)addr_gpa2hva(vm, mmu->pgd);
	for (u16 n1 = 0; n1 <= 0x1ffu; n1++) {
		pml4e = &pml4e_start[n1];
		if (!is_present_pte(mmu, pml4e))
			continue;
		fprintf(stream, "%*spml4e 0x%-3zx %p 0x%-12lx 0x%-10llx %u "
			" %u\n",
			indent, "",
			pml4e - pml4e_start, pml4e,
			addr_hva2gpa(vm, pml4e), PTE_GET_PFN(*pml4e),
			is_writable_pte(mmu, pml4e), is_nx_pte(mmu, pml4e));

		pdpe_start = addr_gpa2hva(vm, *pml4e & PHYSICAL_PAGE_MASK);
		for (u16 n2 = 0; n2 <= 0x1ffu; n2++) {
			pdpe = &pdpe_start[n2];
			if (!is_present_pte(mmu, pdpe))
				continue;
			fprintf(stream, "%*spdpe  0x%-3zx %p 0x%-12lx 0x%-10llx "
				"%u  %u\n",
				indent, "",
				pdpe - pdpe_start, pdpe,
				addr_hva2gpa(vm, pdpe),
				PTE_GET_PFN(*pdpe), is_writable_pte(mmu, pdpe),
				is_nx_pte(mmu, pdpe));

			pde_start = addr_gpa2hva(vm, *pdpe & PHYSICAL_PAGE_MASK);
			for (u16 n3 = 0; n3 <= 0x1ffu; n3++) {
				pde = &pde_start[n3];
				if (!is_present_pte(mmu, pde))
					continue;
				fprintf(stream, "%*spde   0x%-3zx %p "
					"0x%-12lx 0x%-10llx %u  %u\n",
					indent, "", pde - pde_start, pde,
					addr_hva2gpa(vm, pde),
					PTE_GET_PFN(*pde), is_writable_pte(mmu, pde),
					is_nx_pte(mmu, pde));

				pte_start = addr_gpa2hva(vm, *pde & PHYSICAL_PAGE_MASK);
				for (u16 n4 = 0; n4 <= 0x1ffu; n4++) {
					pte = &pte_start[n4];
					if (!is_present_pte(mmu, pte))
						continue;
					fprintf(stream, "%*spte   0x%-3zx %p "
						"0x%-12lx 0x%-10llx %u  %u "
						"    %u    0x%-10lx\n",
						indent, "",
						pte - pte_start, pte,
						addr_hva2gpa(vm, pte),
						PTE_GET_PFN(*pte),
						is_writable_pte(mmu, pte),
						is_nx_pte(mmu, pte),
						is_dirty_pte(mmu, pte),
						((u64)n1 << 27)
							| ((u64)n2 << 18)
							| ((u64)n3 << 9)
							| ((u64)n4));
				}
			}
		}
	}
}

void vm_enable_tdp(struct kvm_vm *vm)
{
	if (kvm_cpu_has(X86_FEATURE_VMX))
		vm_enable_ept(vm);
	else
		vm_enable_npt(vm);
}

bool kvm_cpu_has_tdp(void)
{
	return kvm_cpu_has_ept() || kvm_cpu_has_npt();
}

void __tdp_map(struct kvm_vm *vm, gpa_t l2_gpa, gpa_t gpa, u64 size, int level)
{
	size_t page_size = PG_LEVEL_SIZE(level);
	size_t npages = size / page_size;

	TEST_ASSERT(l2_gpa + size > l2_gpa, "L2 GPA overflow");
	TEST_ASSERT(gpa + size > gpa, "GPA overflow");

	while (npages--) {
		__virt_pg_map(vm, &vm->stage2_mmu, l2_gpa, gpa, level);
		l2_gpa += page_size;
		gpa += page_size;
	}
}

void tdp_map(struct kvm_vm *vm, gpa_t l2_gpa, gpa_t gpa, u64 size)
{
	__tdp_map(vm, l2_gpa, gpa, size, PG_LEVEL_4K);
}

/* Prepare an identity extended page table that maps all the
 * physical pages in VM.
 */
void tdp_identity_map_default_memslots(struct kvm_vm *vm)
{
	u32 s, memslot = 0;
	sparsebit_idx_t i, last;
	struct userspace_mem_region *region = memslot2region(vm, memslot);

	/* Only memslot 0 is mapped here, ensure it's the only one being used */
	for (s = 0; s < NR_MEM_REGIONS; s++)
		TEST_ASSERT_EQ(vm->memslots[s], 0);

	i = (region->region.guest_phys_addr >> vm->page_shift) - 1;
	last = i + (region->region.memory_size >> vm->page_shift);
	for (;;) {
		i = sparsebit_next_clear(region->unused_phy_pages, i);
		if (i > last)
			break;

		tdp_map(vm, (u64)i << vm->page_shift,
			(u64)i << vm->page_shift, 1 << vm->page_shift);
	}
}

/* Identity map a region with 1GiB Pages. */
void tdp_identity_map_1g(struct kvm_vm *vm, u64 addr, u64 size)
{
	__tdp_map(vm, addr, addr, size, PG_LEVEL_1G);
}

/*
 * Set Unusable Segment
 *
 * Input Args: None
 *
 * Output Args:
 *   segp - Pointer to segment register
 *
 * Return: None
 *
 * Sets the segment register pointed to by @segp to an unusable state.
 */
static void kvm_seg_set_unusable(struct kvm_segment *segp)
{
	memset(segp, 0, sizeof(*segp));
	segp->unusable = true;
}

static void kvm_seg_fill_gdt_64bit(struct kvm_vm *vm, struct kvm_segment *segp)
{
	void *gdt = addr_gva2hva(vm, vm->arch.gdt);
	struct desc64 *desc = gdt + (segp->selector >> 3) * 8;

	desc->limit0 = segp->limit & 0xFFFF;
	desc->base0 = segp->base & 0xFFFF;
	desc->base1 = segp->base >> 16;
	desc->type = segp->type;
	desc->s = segp->s;
	desc->dpl = segp->dpl;
	desc->p = segp->present;
	desc->limit1 = segp->limit >> 16;
	desc->avl = segp->avl;
	desc->l = segp->l;
	desc->db = segp->db;
	desc->g = segp->g;
	desc->base2 = segp->base >> 24;
	if (!segp->s)
		desc->base3 = segp->base >> 32;
}

static void kvm_seg_set_kernel_code_64bit(struct kvm_segment *segp)
{
	memset(segp, 0, sizeof(*segp));
	segp->selector = KERNEL_CS;
	segp->limit = 0xFFFFFFFFu;
	segp->s = 0x1; /* kTypeCodeData */
	segp->type = 0x08 | 0x01 | 0x02; /* kFlagCode | kFlagCodeAccessed
					  * | kFlagCodeReadable
					  */
	segp->g = true;
	segp->l = true;
	segp->present = 1;
}

static void kvm_seg_set_kernel_data_64bit(struct kvm_segment *segp)
{
	memset(segp, 0, sizeof(*segp));
	segp->selector = KERNEL_DS;
	segp->limit = 0xFFFFFFFFu;
	segp->s = 0x1; /* kTypeCodeData */
	segp->type = 0x00 | 0x01 | 0x02; /* kFlagData | kFlagDataAccessed
					  * | kFlagDataWritable
					  */
	segp->g = true;
	segp->present = true;
}

gpa_t addr_arch_gva2gpa(struct kvm_vm *vm, gva_t gva)
{
	int level = PG_LEVEL_NONE;
	u64 *pte = __vm_get_page_table_entry(vm, &vm->mmu, gva, &level);

	TEST_ASSERT(is_present_pte(&vm->mmu, pte),
		    "Leaf PTE not PRESENT for gva: 0x%08lx", gva);

	/*
	 * No need for a hugepage mask on the PTE, x86-64 requires the "unused"
	 * address bits to be zero.
	 */
	return vm_untag_gpa(vm, PTE_GET_PA(*pte)) | (gva & ~HUGEPAGE_MASK(level));
}

static void kvm_seg_set_tss_64bit(gva_t base, struct kvm_segment *segp)
{
	memset(segp, 0, sizeof(*segp));
	segp->base = base;
	segp->limit = 0x67;
	segp->selector = KERNEL_TSS;
	segp->type = 0xb;
	segp->present = 1;
}

static void vcpu_init_sregs(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
{
	struct kvm_sregs sregs;

	TEST_ASSERT(vm->mode == VM_MODE_PXXVYY_4K,
		    "Unknown or unsupported guest mode: 0x%x", vm->mode);

	/* Set mode specific system register values. */
	vcpu_sregs_get(vcpu, &sregs);

	sregs.idt.base = vm->arch.idt;
	sregs.idt.limit = NUM_INTERRUPTS * sizeof(struct idt_entry) - 1;
	sregs.gdt.base = vm->arch.gdt;
	sregs.gdt.limit = getpagesize() - 1;

	sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG;
	sregs.cr4 |= X86_CR4_PAE | X86_CR4_OSFXSR;
	if (kvm_cpu_has(X86_FEATURE_XSAVE))
		sregs.cr4 |= X86_CR4_OSXSAVE;
	if (vm->mmu.pgtable_levels == 5)
		sregs.cr4 |= X86_CR4_LA57;
	sregs.efer |= (EFER_LME | EFER_LMA | EFER_NX);

	kvm_seg_set_unusable(&sregs.ldt);
	kvm_seg_set_kernel_code_64bit(&sregs.cs);
	kvm_seg_set_kernel_data_64bit(&sregs.ds);
	kvm_seg_set_kernel_data_64bit(&sregs.es);
	kvm_seg_set_kernel_data_64bit(&sregs.gs);
	kvm_seg_set_tss_64bit(vm->arch.tss, &sregs.tr);

	sregs.cr3 = vm->mmu.pgd;
	vcpu_sregs_set(vcpu, &sregs);
}

static void vcpu_init_xcrs(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
{
	struct kvm_xcrs xcrs = {
		.nr_xcrs = 1,
		.xcrs[0].xcr = 0,
		.xcrs[0].value = kvm_cpu_supported_xcr0(),
	};

	if (!kvm_cpu_has(X86_FEATURE_XSAVE))
		return;

	vcpu_xcrs_set(vcpu, &xcrs);
}

static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
			  int dpl, unsigned short selector)
{
	struct idt_entry *base =
		(struct idt_entry *)addr_gva2hva(vm, vm->arch.idt);
	struct idt_entry *e = &base[vector];

	memset(e, 0, sizeof(*e));
	e->offset0 = addr;
	e->selector = selector;
	e->ist = 0;
	e->type = 14;
	e->dpl = dpl;
	e->p = 1;
	e->offset1 = addr >> 16;
	e->offset2 = addr >> 32;
}

static bool kvm_fixup_exception(struct ex_regs *regs)
{
	if (regs->r9 != KVM_EXCEPTION_MAGIC || regs->rip != regs->r10)
		return false;

	if (regs->vector == DE_VECTOR)
		regs->vector = KVM_MAGIC_DE_VECTOR;

	regs->rip = regs->r11;
	regs->r9 = regs->vector;
	regs->r10 = regs->error_code;
	return true;
}

void route_exception(struct ex_regs *regs)
{
	typedef void(*handler)(struct ex_regs *);
	handler *handlers = (handler *)exception_handlers;

	if (handlers && handlers[regs->vector]) {
		handlers[regs->vector](regs);
		return;
	}

	if (kvm_fixup_exception(regs))
		return;

	GUEST_FAIL("Unhandled exception '0x%lx' at guest RIP '0x%lx'",
		   regs->vector, regs->rip);
}

static void vm_init_descriptor_tables(struct kvm_vm *vm)
{
	extern void *idt_handlers;
	struct kvm_segment seg;
	int i;

	vm->arch.gdt = __vm_alloc_page(vm, MEM_REGION_DATA);
	vm->arch.idt = __vm_alloc_page(vm, MEM_REGION_DATA);
	vm->handlers = __vm_alloc_page(vm, MEM_REGION_DATA);
	vm->arch.tss = __vm_alloc_page(vm, MEM_REGION_DATA);

	/* Handlers have the same address in both address spaces.*/
	for (i = 0; i < NUM_INTERRUPTS; i++)
		set_idt_entry(vm, i, (unsigned long)(&idt_handlers)[i], 0, KERNEL_CS);

	*(gva_t *)addr_gva2hva(vm, (gva_t)(&exception_handlers)) = vm->handlers;

	kvm_seg_set_kernel_code_64bit(&seg);
	kvm_seg_fill_gdt_64bit(vm, &seg);

	kvm_seg_set_kernel_data_64bit(&seg);
	kvm_seg_fill_gdt_64bit(vm, &seg);

	kvm_seg_set_tss_64bit(vm->arch.tss, &seg);
	kvm_seg_fill_gdt_64bit(vm, &seg);
}

void vm_install_exception_handler(struct kvm_vm *vm, int vector,
			       void (*handler)(struct ex_regs *))
{
	gva_t *handlers = (gva_t *)addr_gva2hva(vm, vm->handlers);

	handlers[vector] = (gva_t)handler;
}

void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
{
	struct ucall uc;

	if (get_ucall(vcpu, &uc) == UCALL_ABORT)
		REPORT_GUEST_ASSERT(uc);
}

gva_t vm_alloc_stack(struct kvm_vm *vm, int nr_pages)
{
	int size = nr_pages * getpagesize();
	gva_t stack_gva;

	stack_gva = __vm_alloc(vm, size, DEFAULT_GUEST_STACK_VADDR_MIN, MEM_REGION_DATA);
	stack_gva += size;

	/*
	 * Align stack to match calling sequence requirements in section "The
	 * Stack Frame" of the System V ABI AMD64 Architecture Processor
	 * Supplement, which requires the value (%rsp + 8) to be a multiple of
	 * 16 when control is transferred to the function entry point.
	 *
	 * If this code is ever used to launch a vCPU with 32-bit entry point it
	 * may need to subtract 4 bytes instead of 8 bytes.
	 */
	TEST_ASSERT(IS_ALIGNED(stack_gva, PAGE_SIZE),
		    "__vm_alloc() did not provide a page-aligned address");
	stack_gva -= 8;

	return stack_gva;
}

void kvm_arch_vm_post_create(struct kvm_vm *vm, unsigned int nr_vcpus)
{
	int r;

	TEST_ASSERT(kvm_has_cap(KVM_CAP_GET_TSC_KHZ),
		    "Require KVM_GET_TSC_KHZ to provide udelay() to guest.");

	vm_create_irqchip(vm);
	vm_init_descriptor_tables(vm);

	sync_global_to_guest(vm, host_cpu_is_intel);
	sync_global_to_guest(vm, host_cpu_is_amd);
	sync_global_to_guest(vm, host_cpu_is_hygon);
	sync_global_to_guest(vm, host_cpu_is_amd_compatible);
	sync_global_to_guest(vm, is_forced_emulation_enabled);
	sync_global_to_guest(vm, pmu_errata_mask);

	if (is_sev_vm(vm)) {
		struct kvm_sev_init init = { 0 };

		vm_sev_ioctl(vm, KVM_SEV_INIT2, &init);
	}

	r = __vm_ioctl(vm, KVM_GET_TSC_KHZ, NULL);
	TEST_ASSERT(r > 0, "KVM_GET_TSC_KHZ did not provide a valid TSC frequency.");
	guest_tsc_khz = r;
	sync_global_to_guest(vm, guest_tsc_khz);

	/*
	 * The guest MMU is just a placeholder to provide access to PTE masks
	 * (for now). The guest does not have mappings for its own page tables
	 * by default, so any meaningful use of guest page tables requires
	 * explicit setup by the test. Zero the PGD to make it obvious the guest
	 * page tables are not immediately usable by guest code.
	 */
	guest_mmu = vm->mmu;
	guest_mmu.pgd = 0;
	sync_global_to_guest(vm, guest_mmu);
}

void vcpu_arch_set_entry_point(struct kvm_vcpu *vcpu, void *guest_code)
{
	struct kvm_regs regs;

	vcpu_regs_get(vcpu, &regs);
	regs.rip = (unsigned long) guest_code;
	vcpu_regs_set(vcpu, &regs);
}

struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, u32 vcpu_id)
{
	struct kvm_mp_state mp_state;
	struct kvm_regs regs;
	struct kvm_vcpu *vcpu;

	vcpu = __vm_vcpu_add(vm, vcpu_id);
	vcpu_init_cpuid(vcpu, kvm_get_supported_cpuid());
	vcpu_init_sregs(vm, vcpu);
	vcpu_init_xcrs(vm, vcpu);

	/* Setup guest general purpose registers */
	vcpu_regs_get(vcpu, &regs);
	regs.rflags = regs.rflags | X86_EFLAGS_FIXED;
	regs.rsp = vm_alloc_stack(vm, DEFAULT_STACK_PGS);
	vcpu_regs_set(vcpu, &regs);

	/* Setup the MP state */
	mp_state.mp_state = 0;
	vcpu_mp_state_set(vcpu, &mp_state);

	/*
	 * Refresh CPUID after setting SREGS and XCR0, so that KVM's "runtime"
	 * updates to guest CPUID, e.g. for OSXSAVE and XSAVE state size, are
	 * reflected into selftests' vCPU CPUID cache, i.e. so that the cache
	 * is consistent with vCPU state.
	 */
	vcpu_get_cpuid(vcpu);
	return vcpu;
}

struct kvm_vcpu *vm_arch_vcpu_recreate(struct kvm_vm *vm, u32 vcpu_id)
{
	struct kvm_vcpu *vcpu = __vm_vcpu_add(vm, vcpu_id);

	vcpu_init_cpuid(vcpu, kvm_get_supported_cpuid());

	return vcpu;
}

void vcpu_arch_free(struct kvm_vcpu *vcpu)
{
	if (vcpu->cpuid)
		free(vcpu->cpuid);
}

/* Do not use kvm_supported_cpuid directly except for validity checks. */
static void *kvm_supported_cpuid;

const struct kvm_cpuid2 *kvm_get_supported_cpuid(void)
{
	int kvm_fd;

	if (kvm_supported_cpuid)
		return kvm_supported_cpuid;

	kvm_supported_cpuid = allocate_kvm_cpuid2(MAX_NR_CPUID_ENTRIES);
	kvm_fd = open_kvm_dev_path_or_exit();

	kvm_ioctl(kvm_fd, KVM_GET_SUPPORTED_CPUID,
		  (struct kvm_cpuid2 *)kvm_supported_cpuid);

	close(kvm_fd);
	return kvm_supported_cpuid;
}

static u32 __kvm_cpu_has(const struct kvm_cpuid2 *cpuid,
			 u32 function, u32 index,
			 u8 reg, u8 lo, u8 hi)
{
	const struct kvm_cpuid_entry2 *entry;
	int i;

	for (i = 0; i < cpuid->nent; i++) {
		entry = &cpuid->entries[i];

		/*
		 * The output registers in kvm_cpuid_entry2 are in alphabetical
		 * order, but kvm_x86_cpu_feature matches that mess, so yay
		 * pointer shenanigans!
		 */
		if (entry->function == function && entry->index == index)
			return ((&entry->eax)[reg] & GENMASK(hi, lo)) >> lo;
	}

	return 0;
}

bool kvm_cpuid_has(const struct kvm_cpuid2 *cpuid,
		   struct kvm_x86_cpu_feature feature)
{
	return __kvm_cpu_has(cpuid, feature.function, feature.index,
			     feature.reg, feature.bit, feature.bit);
}

u32 kvm_cpuid_property(const struct kvm_cpuid2 *cpuid,
		       struct kvm_x86_cpu_property property)
{
	return __kvm_cpu_has(cpuid, property.function, property.index,
			     property.reg, property.lo_bit, property.hi_bit);
}

u64 kvm_get_feature_msr(u64 msr_index)
{
	struct {
		struct kvm_msrs header;
		struct kvm_msr_entry entry;
	} buffer = {};
	int r, kvm_fd;

	buffer.header.nmsrs = 1;
	buffer.entry.index = msr_index;
	kvm_fd = open_kvm_dev_path_or_exit();

	r = __kvm_ioctl(kvm_fd, KVM_GET_MSRS, &buffer.header);
	TEST_ASSERT(r == 1, KVM_IOCTL_ERROR(KVM_GET_MSRS, r));

	close(kvm_fd);
	return buffer.entry.data;
}

void __vm_xsave_require_permission(u64 xfeature, const char *name)
{
	int kvm_fd;
	u64 bitmask;
	long rc;
	struct kvm_device_attr attr = {
		.group = 0,
		.attr = KVM_X86_XCOMP_GUEST_SUPP,
		.addr = (unsigned long) &bitmask,
	};

	TEST_ASSERT(!kvm_supported_cpuid,
		    "kvm_get_supported_cpuid() cannot be used before ARCH_REQ_XCOMP_GUEST_PERM");

	TEST_ASSERT(is_power_of_2(xfeature),
		    "Dynamic XFeatures must be enabled one at a time");

	kvm_fd = open_kvm_dev_path_or_exit();
	rc = __kvm_ioctl(kvm_fd, KVM_GET_DEVICE_ATTR, &attr);
	close(kvm_fd);

	if (rc == -1 && (errno == ENXIO || errno == EINVAL))
		__TEST_REQUIRE(0, "KVM_X86_XCOMP_GUEST_SUPP not supported");

	TEST_ASSERT(rc == 0, "KVM_GET_DEVICE_ATTR(0, KVM_X86_XCOMP_GUEST_SUPP) error: %ld", rc);

	__TEST_REQUIRE(bitmask & xfeature,
		       "Required XSAVE feature '%s' not supported", name);

	TEST_REQUIRE(!syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_GUEST_PERM, ilog2(xfeature)));

	rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_GUEST_PERM, &bitmask);
	TEST_ASSERT(rc == 0, "prctl(ARCH_GET_XCOMP_GUEST_PERM) error: %ld", rc);
	TEST_ASSERT(bitmask & xfeature,
		    "'%s' (0x%lx) not permitted after prctl(ARCH_REQ_XCOMP_GUEST_PERM) permitted=0x%lx",
		    name, xfeature, bitmask);
}

void vcpu_init_cpuid(struct kvm_vcpu *vcpu, const struct kvm_cpuid2 *cpuid)
{
	TEST_ASSERT(cpuid != vcpu->cpuid, "@cpuid can't be the vCPU's CPUID");

	/* Allow overriding the default CPUID. */
	if (vcpu->cpuid && vcpu->cpuid->nent < cpuid->nent) {
		free(vcpu->cpuid);
		vcpu->cpuid = NULL;
	}

	if (!vcpu->cpuid)
		vcpu->cpuid = allocate_kvm_cpuid2(cpuid->nent);

	memcpy(vcpu->cpuid, cpuid, kvm_cpuid2_size(cpuid->nent));
	vcpu_set_cpuid(vcpu);
}

void vcpu_set_cpuid_property(struct kvm_vcpu *vcpu,
			     struct kvm_x86_cpu_property property,
			     u32 value)
{
	struct kvm_cpuid_entry2 *entry;

	entry = __vcpu_get_cpuid_entry(vcpu, property.function, property.index);

	(&entry->eax)[property.reg] &= ~GENMASK(property.hi_bit, property.lo_bit);
	(&entry->eax)[property.reg] |= value << property.lo_bit;

	vcpu_set_cpuid(vcpu);

	/* Sanity check that @value doesn't exceed the bounds in any way. */
	TEST_ASSERT_EQ(kvm_cpuid_property(vcpu->cpuid, property), value);
}

void vcpu_clear_cpuid_entry(struct kvm_vcpu *vcpu, u32 function)
{
	struct kvm_cpuid_entry2 *entry = vcpu_get_cpuid_entry(vcpu, function);

	entry->eax = 0;
	entry->ebx = 0;
	entry->ecx = 0;
	entry->edx = 0;
	vcpu_set_cpuid(vcpu);
}

void vcpu_set_or_clear_cpuid_feature(struct kvm_vcpu *vcpu,
				     struct kvm_x86_cpu_feature feature,
				     bool set)
{
	struct kvm_cpuid_entry2 *entry;
	u32 *reg;

	entry = __vcpu_get_cpuid_entry(vcpu, feature.function, feature.index);
	reg = (&entry->eax) + feature.reg;

	if (set)
		*reg |= BIT(feature.bit);
	else
		*reg &= ~BIT(feature.bit);

	vcpu_set_cpuid(vcpu);
}

u64 vcpu_get_msr(struct kvm_vcpu *vcpu, u64 msr_index)
{
	struct {
		struct kvm_msrs header;
		struct kvm_msr_entry entry;
	} buffer = {};

	buffer.header.nmsrs = 1;
	buffer.entry.index = msr_index;

	vcpu_msrs_get(vcpu, &buffer.header);

	return buffer.entry.data;
}

int _vcpu_set_msr(struct kvm_vcpu *vcpu, u64 msr_index, u64 msr_value)
{
	struct {
		struct kvm_msrs header;
		struct kvm_msr_entry entry;
	} buffer = {};

	memset(&buffer, 0, sizeof(buffer));
	buffer.header.nmsrs = 1;
	buffer.entry.index = msr_index;
	buffer.entry.data = msr_value;

	return __vcpu_ioctl(vcpu, KVM_SET_MSRS, &buffer.header);
}

void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...)
{
	va_list ap;
	struct kvm_regs regs;

	TEST_ASSERT(num >= 1 && num <= 6, "Unsupported number of args,\n"
		    "  num: %u",
		    num);

	va_start(ap, num);
	vcpu_regs_get(vcpu, &regs);

	if (num >= 1)
		regs.rdi = va_arg(ap, u64);

	if (num >= 2)
		regs.rsi = va_arg(ap, u64);

	if (num >= 3)
		regs.rdx = va_arg(ap, u64);

	if (num >= 4)
		regs.rcx = va_arg(ap, u64);

	if (num >= 5)
		regs.r8 = va_arg(ap, u64);

	if (num >= 6)
		regs.r9 = va_arg(ap, u64);

	vcpu_regs_set(vcpu, &regs);
	va_end(ap);
}

void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, u8 indent)
{
	struct kvm_regs regs;
	struct kvm_sregs sregs;

	fprintf(stream, "%*svCPU ID: %u\n", indent, "", vcpu->id);

	fprintf(stream, "%*sregs:\n", indent + 2, "");
	vcpu_regs_get(vcpu, &regs);
	regs_dump(stream, &regs, indent + 4);

	fprintf(stream, "%*ssregs:\n", indent + 2, "");
	vcpu_sregs_get(vcpu, &sregs);
	sregs_dump(stream, &sregs, indent + 4);
}

static struct kvm_msr_list *__kvm_get_msr_index_list(bool feature_msrs)
{
	struct kvm_msr_list *list;
	struct kvm_msr_list nmsrs;
	int kvm_fd, r;

	kvm_fd = open_kvm_dev_path_or_exit();

	nmsrs.nmsrs = 0;
	if (!feature_msrs)
		r = __kvm_ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, &nmsrs);
	else
		r = __kvm_ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, &nmsrs);

	TEST_ASSERT(r == -1 && errno == E2BIG,
		    "Expected -E2BIG, got rc: %i errno: %i (%s)",
		    r, errno, strerror(errno));

	list = malloc(sizeof(*list) + nmsrs.nmsrs * sizeof(list->indices[0]));
	TEST_ASSERT(list, "-ENOMEM when allocating MSR index list");
	list->nmsrs = nmsrs.nmsrs;

	if (!feature_msrs)
		kvm_ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list);
	else
		kvm_ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
	close(kvm_fd);

	TEST_ASSERT(list->nmsrs == nmsrs.nmsrs,
		    "Number of MSRs in list changed, was %d, now %d",
		    nmsrs.nmsrs, list->nmsrs);
	return list;
}

const struct kvm_msr_list *kvm_get_msr_index_list(void)
{
	static const struct kvm_msr_list *list;

	if (!list)
		list = __kvm_get_msr_index_list(false);
	return list;
}


const struct kvm_msr_list *kvm_get_feature_msr_index_list(void)
{
	static const struct kvm_msr_list *list;

	if (!list)
		list = __kvm_get_msr_index_list(true);
	return list;
}

bool kvm_msr_is_in_save_restore_list(u32 msr_index)
{
	const struct kvm_msr_list *list = kvm_get_msr_index_list();
	int i;

	for (i = 0; i < list->nmsrs; ++i) {
		if (list->indices[i] == msr_index)
			return true;
	}

	return false;
}

static void vcpu_save_xsave_state(struct kvm_vcpu *vcpu,
				  struct kvm_x86_state *state)
{
	int size = vm_check_cap(vcpu->vm, KVM_CAP_XSAVE2);

	if (size) {
		state->xsave = malloc(size);
		vcpu_xsave2_get(vcpu, state->xsave);
	} else {
		state->xsave = malloc(sizeof(struct kvm_xsave));
		vcpu_xsave_get(vcpu, state->xsave);
	}
}

struct kvm_x86_state *vcpu_save_state(struct kvm_vcpu *vcpu)
{
	const struct kvm_msr_list *msr_list = kvm_get_msr_index_list();
	struct kvm_x86_state *state;
	int i;

	static int nested_size = -1;

	if (nested_size == -1) {
		nested_size = kvm_check_cap(KVM_CAP_NESTED_STATE);
		TEST_ASSERT(nested_size <= sizeof(state->nested_),
			    "Nested state size too big, %i > %zi",
			    nested_size, sizeof(state->nested_));
	}

	/*
	 * When KVM exits to userspace with KVM_EXIT_IO, KVM guarantees
	 * guest state is consistent only after userspace re-enters the
	 * kernel with KVM_RUN.  Complete IO prior to migrating state
	 * to a new VM.
	 */
	vcpu_run_complete_io(vcpu);

	state = malloc(sizeof(*state) + msr_list->nmsrs * sizeof(state->msrs.entries[0]));
	TEST_ASSERT(state, "-ENOMEM when allocating kvm state");

	vcpu_events_get(vcpu, &state->events);
	vcpu_mp_state_get(vcpu, &state->mp_state);
	vcpu_regs_get(vcpu, &state->regs);
	vcpu_save_xsave_state(vcpu, state);

	if (kvm_has_cap(KVM_CAP_XCRS))
		vcpu_xcrs_get(vcpu, &state->xcrs);

	vcpu_sregs_get(vcpu, &state->sregs);

	if (nested_size) {
		state->nested.size = sizeof(state->nested_);

		vcpu_nested_state_get(vcpu, &state->nested);
		TEST_ASSERT(state->nested.size <= nested_size,
			    "Nested state size too big, %i (KVM_CHECK_CAP gave %i)",
			    state->nested.size, nested_size);
	} else {
		state->nested.size = 0;
	}

	state->msrs.nmsrs = msr_list->nmsrs;
	for (i = 0; i < msr_list->nmsrs; i++)
		state->msrs.entries[i].index = msr_list->indices[i];
	vcpu_msrs_get(vcpu, &state->msrs);

	vcpu_debugregs_get(vcpu, &state->debugregs);

	return state;
}

void vcpu_load_state(struct kvm_vcpu *vcpu, struct kvm_x86_state *state)
{
	vcpu_sregs_set(vcpu, &state->sregs);
	vcpu_msrs_set(vcpu, &state->msrs);

	if (kvm_has_cap(KVM_CAP_XCRS))
		vcpu_xcrs_set(vcpu, &state->xcrs);

	vcpu_xsave_set(vcpu,  state->xsave);
	vcpu_events_set(vcpu, &state->events);
	vcpu_mp_state_set(vcpu, &state->mp_state);
	vcpu_debugregs_set(vcpu, &state->debugregs);
	vcpu_regs_set(vcpu, &state->regs);

	if (state->nested.size)
		vcpu_nested_state_set(vcpu, &state->nested);
}

void kvm_x86_state_cleanup(struct kvm_x86_state *state)
{
	free(state->xsave);
	free(state);
}

void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits)
{
	if (!kvm_cpu_has_p(X86_PROPERTY_MAX_PHY_ADDR)) {
		*pa_bits = kvm_cpu_has(X86_FEATURE_PAE) ? 36 : 32;
		*va_bits = 32;
	} else {
		*pa_bits = kvm_cpu_property(X86_PROPERTY_MAX_PHY_ADDR);
		*va_bits = kvm_cpu_property(X86_PROPERTY_MAX_VIRT_ADDR);
	}
}

void kvm_init_vm_address_properties(struct kvm_vm *vm)
{
	if (is_sev_vm(vm)) {
		vm->arch.sev_fd = open_sev_dev_path_or_exit();
		vm->arch.c_bit = BIT_ULL(this_cpu_property(X86_PROPERTY_SEV_C_BIT));
		vm->gpa_tag_mask = vm->arch.c_bit;
	} else {
		vm->arch.sev_fd = -1;
	}
}

const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,
					       u32 function, u32 index)
{
	int i;

	for (i = 0; i < cpuid->nent; i++) {
		if (cpuid->entries[i].function == function &&
		    cpuid->entries[i].index == index)
			return &cpuid->entries[i];
	}

	TEST_FAIL("CPUID function 0x%x index 0x%x not found ", function, index);

	return NULL;
}

#define X86_HYPERCALL(inputs...)					\
({									\
	u64 r;							\
									\
	asm volatile("test %[use_vmmcall], %[use_vmmcall]\n\t"		\
		     "jnz 1f\n\t"					\
		     "vmcall\n\t"					\
		     "jmp 2f\n\t"					\
		     "1: vmmcall\n\t"					\
		     "2:"						\
		     : "=a"(r)						\
		     : [use_vmmcall] "r" (host_cpu_is_amd_compatible),	\
		       inputs);						\
									\
	r;								\
})

u64 kvm_hypercall(u64 nr, u64 a0, u64 a1, u64 a2, u64 a3)
{
	return X86_HYPERCALL("a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3));
}

u64 __xen_hypercall(u64 nr, u64 a0, void *a1)
{
	return X86_HYPERCALL("a"(nr), "D"(a0), "S"(a1));
}

void xen_hypercall(u64 nr, u64 a0, void *a1)
{
	GUEST_ASSERT(!__xen_hypercall(nr, a0, a1));
}

unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
{
	const unsigned long num_ht_pages = 12 << (30 - vm->page_shift); /* 12 GiB */
	unsigned long ht_gfn, max_gfn, max_pfn;
	u8 maxphyaddr, guest_maxphyaddr;

	/*
	 * Use "guest MAXPHYADDR" from KVM if it's available.  Guest MAXPHYADDR
	 * enumerates the max _mappable_ GPA, which can be less than the raw
	 * MAXPHYADDR, e.g. if MAXPHYADDR=52, KVM is using TDP, and the CPU
	 * doesn't support 5-level TDP.
	 */
	guest_maxphyaddr = kvm_cpu_property(X86_PROPERTY_GUEST_MAX_PHY_ADDR);
	guest_maxphyaddr = guest_maxphyaddr ?: vm->pa_bits;
	TEST_ASSERT(guest_maxphyaddr <= vm->pa_bits,
		    "Guest MAXPHYADDR should never be greater than raw MAXPHYADDR");

	max_gfn = (1ULL << (guest_maxphyaddr - vm->page_shift)) - 1;

	/* Avoid reserved HyperTransport region on AMD or Hygon processors. */
	if (!host_cpu_is_amd_compatible)
		return max_gfn;

	/* On parts with <40 physical address bits, the area is fully hidden */
	if (vm->pa_bits < 40)
		return max_gfn;

	/* Before family 17h, the HyperTransport area is just below 1T.  */
	ht_gfn = (1 << 28) - num_ht_pages;
	if (this_cpu_family() < 0x17)
		goto done;

	/*
	 * Otherwise it's at the top of the physical address space, possibly
	 * reduced due to SME or CSV by bits 11:6 of CPUID[0x8000001f].EBX.  Use
	 * the old conservative value if MAXPHYADDR is not enumerated.
	 */
	if (!this_cpu_has_p(X86_PROPERTY_MAX_PHY_ADDR))
		goto done;

	maxphyaddr = this_cpu_property(X86_PROPERTY_MAX_PHY_ADDR);
	max_pfn = (1ULL << (maxphyaddr - vm->page_shift)) - 1;

	if (this_cpu_has_p(X86_PROPERTY_PHYS_ADDR_REDUCTION))
		max_pfn >>= this_cpu_property(X86_PROPERTY_PHYS_ADDR_REDUCTION);

	ht_gfn = max_pfn - num_ht_pages;
done:
	return min(max_gfn, ht_gfn - 1);
}

void kvm_selftest_arch_init(void)
{
	host_cpu_is_intel = this_cpu_is_intel();
	host_cpu_is_amd = this_cpu_is_amd();
	host_cpu_is_hygon = this_cpu_is_hygon();
	host_cpu_is_amd_compatible = host_cpu_is_amd || host_cpu_is_hygon;
	is_forced_emulation_enabled = kvm_is_forced_emulation_enabled();

	kvm_init_pmu_errata();
}

bool sys_clocksource_is_based_on_tsc(void)
{
	char *clk_name = sys_get_cur_clocksource();
	bool ret = !strcmp(clk_name, "tsc\n") ||
		   !strcmp(clk_name, "hyperv_clocksource_tsc_page\n");

	free(clk_name);

	return ret;
}

bool kvm_arch_has_default_irqchip(void)
{
	return true;
}

void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, u64 smram_gpa,
		 const void *smi_handler, size_t handler_size)
{
	vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, smram_gpa,
				    SMRAM_MEMSLOT, SMRAM_PAGES, 0);
	TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, smram_gpa,
				       SMRAM_MEMSLOT) == smram_gpa,
		    "Could not allocate guest physical addresses for SMRAM");

	memset(addr_gpa2hva(vm, smram_gpa), 0x0, SMRAM_SIZE);
	memcpy(addr_gpa2hva(vm, smram_gpa) + 0x8000, smi_handler, handler_size);
	vcpu_set_msr(vcpu, MSR_IA32_SMBASE, smram_gpa);
}

void inject_smi(struct kvm_vcpu *vcpu)
{
	struct kvm_vcpu_events events;

	vcpu_events_get(vcpu, &events);
	events.smi.pending = 1;
	events.flags |= KVM_VCPUEVENT_VALID_SMM;
	vcpu_events_set(vcpu, &events);
}
