// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020, Google LLC.
 *
 * Test that KVM emulates instructions in response to EPT violations when
 * allow_smaller_maxphyaddr is enabled and guest.MAXPHYADDR < host.MAXPHYADDR.
 */

#define _GNU_SOURCE /* for program_invocation_short_name */

#include "flds_emulation.h"

#include "test_util.h"
#include "kvm_util.h"
#include "vmx.h"

#define MAXPHYADDR 36

#define MEM_REGION_GVA	0x0000123456789000
#define MEM_REGION_GPA	0x0000000700000000
#define MEM_REGION_SLOT	10
#define MEM_REGION_SIZE PAGE_SIZE

static void guest_code(bool tdp_enabled)
{
	uint64_t error_code;
	uint64_t vector;

	vector = kvm_asm_safe_ec(FLDS_MEM_EAX, error_code, "a"(MEM_REGION_GVA));

	/*
	 * When TDP is enabled, flds will trigger an emulation failure, exit to
	 * userspace, and then the selftest host "VMM" skips the instruction.
	 *
	 * When TDP is disabled, no instruction emulation is required so flds
	 * should generate #PF(RSVD).
	 */
	if (tdp_enabled) {
		GUEST_ASSERT(!vector);
	} else {
		GUEST_ASSERT_EQ(vector, PF_VECTOR);
		GUEST_ASSERT(error_code & PFERR_RSVD_MASK);
	}

	GUEST_DONE();
}

int main(int argc, char *argv[])
{
	struct kvm_vcpu *vcpu;
	struct kvm_vm *vm;
	struct ucall uc;
	uint64_t *pte;
	uint64_t *hva;
	uint64_t gpa;
	int rc;

	TEST_REQUIRE(kvm_has_cap(KVM_CAP_SMALLER_MAXPHYADDR));

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
	vcpu_args_set(vcpu, 1, kvm_is_tdp_enabled());

	vm_init_descriptor_tables(vm);
	vcpu_init_descriptor_tables(vcpu);

	vcpu_set_cpuid_maxphyaddr(vcpu, MAXPHYADDR);

	rc = kvm_check_cap(KVM_CAP_EXIT_ON_EMULATION_FAILURE);
	TEST_ASSERT(rc, "KVM_CAP_EXIT_ON_EMULATION_FAILURE is unavailable");
	vm_enable_cap(vm, KVM_CAP_EXIT_ON_EMULATION_FAILURE, 1);

	vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
				    MEM_REGION_GPA, MEM_REGION_SLOT,
				    MEM_REGION_SIZE / PAGE_SIZE, 0);
	gpa = vm_phy_pages_alloc(vm, MEM_REGION_SIZE / PAGE_SIZE,
				 MEM_REGION_GPA, MEM_REGION_SLOT);
	TEST_ASSERT(gpa == MEM_REGION_GPA, "Failed vm_phy_pages_alloc\n");
	virt_map(vm, MEM_REGION_GVA, MEM_REGION_GPA, 1);
	hva = addr_gpa2hva(vm, MEM_REGION_GPA);
	memset(hva, 0, PAGE_SIZE);

	pte = vm_get_page_table_entry(vm, MEM_REGION_GVA);
	*pte |= BIT_ULL(MAXPHYADDR);

	vcpu_run(vcpu);

	/*
	 * When TDP is enabled, KVM must emulate in response the guest physical
	 * address that is illegal from the guest's perspective, but is legal
	 * from hardware's perspeective.  This should result in an emulation
	 * failure exit to userspace since KVM doesn't support emulating flds.
	 */
	if (kvm_is_tdp_enabled()) {
		handle_flds_emulation_failure_exit(vcpu);
		vcpu_run(vcpu);
	}

	switch (get_ucall(vcpu, &uc)) {
	case UCALL_ABORT:
		REPORT_GUEST_ASSERT(uc);
		break;
	case UCALL_DONE:
		break;
	default:
		TEST_FAIL("Unrecognized ucall: %lu\n", uc.cmd);
	}

	kvm_vm_free(vm);

	return 0;
}
