// SPDX-License-Identifier: GPL-2.0-only

/* hypercalls: Check the ARM64's psuedo-firmware bitmap register interface.
 *
 * The test validates the basic hypercall functionalities that are exposed
 * via the psuedo-firmware bitmap register. This includes the registers'
 * read/write behavior before and after the VM has started, and if the
 * hypercalls are properly masked or unmasked to the guest when disabled or
 * enabled from the KVM userspace, respectively.
 */
#include <errno.h>
#include <linux/arm-smccc.h>
#include <asm/kvm.h>
#include <kvm_util.h>

#include "processor.h"

#define FW_REG_ULIMIT_VAL(max_feat_bit) (GENMASK(max_feat_bit, 0))

/* Last valid bits of the bitmapped firmware registers */
#define KVM_REG_ARM_STD_BMAP_BIT_MAX		0
#define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX	0
#define KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX	1
#define KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_MAX   1

#define KVM_REG_ARM_STD_BMAP_RESET_VAL		FW_REG_ULIMIT_VAL(KVM_REG_ARM_STD_BMAP_BIT_MAX)
#define KVM_REG_ARM_STD_HYP_BMAP_RESET_VAL	FW_REG_ULIMIT_VAL(KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX)
#define KVM_REG_ARM_VENDOR_HYP_BMAP_RESET_VAL	FW_REG_ULIMIT_VAL(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX)
#define KVM_REG_ARM_VENDOR_HYP_BMAP_2_RESET_VAL 0

struct kvm_fw_reg_info {
	u64 reg;		/* Register definition */
	u64 max_feat_bit;	/* Bit that represents the upper limit of the feature-map */
	u64 reset_val;	/* Reset value for the register */
};

#define FW_REG_INFO(r)			\
	{					\
		.reg = r,			\
		.max_feat_bit = r##_BIT_MAX,	\
		.reset_val = r##_RESET_VAL	\
	}

static const struct kvm_fw_reg_info fw_reg_info[] = {
	FW_REG_INFO(KVM_REG_ARM_STD_BMAP),
	FW_REG_INFO(KVM_REG_ARM_STD_HYP_BMAP),
	FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP),
	FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP_2),
};

enum test_stage {
	TEST_STAGE_REG_IFACE,
	TEST_STAGE_HVC_IFACE_FEAT_DISABLED,
	TEST_STAGE_HVC_IFACE_FEAT_ENABLED,
	TEST_STAGE_HVC_IFACE_FALSE_INFO,
	TEST_STAGE_END,
};

static int stage = TEST_STAGE_REG_IFACE;

struct test_hvc_info {
	u32 func_id;
	u64 arg1;
};

#define TEST_HVC_INFO(f, a1)	\
	{			\
		.func_id = f,	\
		.arg1 = a1,	\
	}

static const struct test_hvc_info hvc_info[] = {
	/* KVM_REG_ARM_STD_BMAP */
	TEST_HVC_INFO(ARM_SMCCC_TRNG_VERSION, 0),
	TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_TRNG_RND64),
	TEST_HVC_INFO(ARM_SMCCC_TRNG_GET_UUID, 0),
	TEST_HVC_INFO(ARM_SMCCC_TRNG_RND32, 0),
	TEST_HVC_INFO(ARM_SMCCC_TRNG_RND64, 0),

	/* KVM_REG_ARM_STD_HYP_BMAP */
	TEST_HVC_INFO(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_HV_PV_TIME_FEATURES),
	TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES, ARM_SMCCC_HV_PV_TIME_ST),
	TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_ST, 0),

	/* KVM_REG_ARM_VENDOR_HYP_BMAP */
	TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID,
			ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID),
	TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, 0),
	TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, KVM_PTP_VIRT_COUNTER),
};

/* Feed false hypercall info to test the KVM behavior */
static const struct test_hvc_info false_hvc_info[] = {
	/* Feature support check against a different family of hypercalls */
	TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID),
	TEST_HVC_INFO(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_TRNG_RND64),
	TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES, ARM_SMCCC_TRNG_RND64),
};

static void guest_test_hvc(const struct test_hvc_info *hc_info)
{
	unsigned int i;
	struct arm_smccc_res res;
	unsigned int hvc_info_arr_sz;

	hvc_info_arr_sz =
	hc_info == hvc_info ? ARRAY_SIZE(hvc_info) : ARRAY_SIZE(false_hvc_info);

	for (i = 0; i < hvc_info_arr_sz; i++, hc_info++) {
		memset(&res, 0, sizeof(res));
		do_smccc(hc_info->func_id, hc_info->arg1, 0, 0, 0, 0, 0, 0, &res);

		switch (stage) {
		case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
		case TEST_STAGE_HVC_IFACE_FALSE_INFO:
			__GUEST_ASSERT(res.a0 == SMCCC_RET_NOT_SUPPORTED,
				       "a0 = 0x%lx, func_id = 0x%x, arg1 = 0x%lx, stage = %u",
					res.a0, hc_info->func_id, hc_info->arg1, stage);
			break;
		case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
			__GUEST_ASSERT(res.a0 != SMCCC_RET_NOT_SUPPORTED,
				       "a0 = 0x%lx, func_id = 0x%x, arg1 = 0x%lx, stage = %u",
					res.a0, hc_info->func_id, hc_info->arg1, stage);
			break;
		default:
			GUEST_FAIL("Unexpected stage = %u", stage);
		}
	}
}

static void guest_code(void)
{
	while (stage != TEST_STAGE_END) {
		switch (stage) {
		case TEST_STAGE_REG_IFACE:
			break;
		case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
		case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
			guest_test_hvc(hvc_info);
			break;
		case TEST_STAGE_HVC_IFACE_FALSE_INFO:
			guest_test_hvc(false_hvc_info);
			break;
		default:
			GUEST_FAIL("Unexpected stage = %u", stage);
		}

		GUEST_SYNC(stage);
	}

	GUEST_DONE();
}

struct st_time {
	u32 rev;
	u32 attr;
	u64 st_time;
};

#define STEAL_TIME_SIZE		((sizeof(struct st_time) + 63) & ~63)
#define ST_GPA_BASE		(1 << 30)

static void steal_time_init(struct kvm_vcpu *vcpu)
{
	u64 st_ipa = (ulong)ST_GPA_BASE;
	unsigned int gpages;

	gpages = vm_calc_num_guest_pages(VM_MODE_DEFAULT, STEAL_TIME_SIZE);
	vm_userspace_mem_region_add(vcpu->vm, VM_MEM_SRC_ANONYMOUS, ST_GPA_BASE, 1, gpages, 0);

	vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PVTIME_CTRL,
			     KVM_ARM_VCPU_PVTIME_IPA, &st_ipa);
}

static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
{
	u64 val;
	unsigned int i;
	int ret;

	for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) {
		const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
		u64 set_val;

		/* First 'read' should be the reset value for the reg  */
		val = vcpu_get_reg(vcpu, reg_info->reg);
		TEST_ASSERT(val == reg_info->reset_val,
			"Unexpected reset value for reg: 0x%lx; expected: 0x%lx; read: 0x%lx",
			reg_info->reg, reg_info->reset_val, val);

		if (reg_info->reset_val)
			set_val = 0;
		else
			set_val = FW_REG_ULIMIT_VAL(reg_info->max_feat_bit);

		ret = __vcpu_set_reg(vcpu, reg_info->reg, set_val);
		TEST_ASSERT(ret == 0,
			"Failed to %s all the features of reg: 0x%lx; ret: %d",
			(set_val ? "set" : "clear"), reg_info->reg, errno);

		val = vcpu_get_reg(vcpu, reg_info->reg);
		TEST_ASSERT(val == set_val,
			"Expected all the features to be %s for reg: 0x%lx",
			(set_val ? "set" : "cleared"), reg_info->reg);

		/*
		 * If the reg has been set, clear it as test_fw_regs_after_vm_start()
		 * expects it to be cleared.
		 */
		if (set_val) {
			ret = __vcpu_set_reg(vcpu, reg_info->reg, 0);
			TEST_ASSERT(ret == 0,
			"Failed to clear all the features of reg: 0x%lx; ret: %d",
			reg_info->reg, errno);
		}

		/*
		 * Test enabling a feature that's not supported.
		 * Avoid this check if all the bits are occupied.
		 */
		if (reg_info->max_feat_bit < 63) {
			ret = __vcpu_set_reg(vcpu, reg_info->reg, BIT(reg_info->max_feat_bit + 1));
			TEST_ASSERT(ret != 0 && errno == EINVAL,
			"Unexpected behavior or return value (%d) while setting an unsupported feature for reg: 0x%lx",
			errno, reg_info->reg);
		}
	}
}

static void test_fw_regs_after_vm_start(struct kvm_vcpu *vcpu)
{
	u64 val;
	unsigned int i;
	int ret;

	for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) {
		const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];

		/*
		 * Before starting the VM, the test clears all the bits.
		 * Check if that's still the case.
		 */
		val = vcpu_get_reg(vcpu, reg_info->reg);
		TEST_ASSERT(val == 0,
			"Expected all the features to be cleared for reg: 0x%lx",
			reg_info->reg);

		/*
		 * Since the VM has run at least once, KVM shouldn't allow modification of
		 * the registers and should return EBUSY. Set the registers and check for
		 * the expected errno.
		 */
		ret = __vcpu_set_reg(vcpu, reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit));
		TEST_ASSERT(ret != 0 && errno == EBUSY,
		"Unexpected behavior or return value (%d) while setting a feature while VM is running for reg: 0x%lx",
		errno, reg_info->reg);
	}
}

static struct kvm_vm *test_vm_create(struct kvm_vcpu **vcpu)
{
	struct kvm_vm *vm;

	vm = vm_create_with_one_vcpu(vcpu, guest_code);

	steal_time_init(*vcpu);

	return vm;
}

static void test_guest_stage(struct kvm_vm **vm, struct kvm_vcpu **vcpu)
{
	int prev_stage = stage;

	pr_debug("Stage: %d\n", prev_stage);

	/* Sync the stage early, the VM might be freed below. */
	stage++;
	sync_global_to_guest(*vm, stage);

	switch (prev_stage) {
	case TEST_STAGE_REG_IFACE:
		test_fw_regs_after_vm_start(*vcpu);
		break;
	case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
		/* Start a new VM so that all the features are now enabled by default */
		kvm_vm_free(*vm);
		*vm = test_vm_create(vcpu);
		break;
	case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
	case TEST_STAGE_HVC_IFACE_FALSE_INFO:
		break;
	default:
		TEST_FAIL("Unknown test stage: %d", prev_stage);
	}
}

static void test_run(void)
{
	struct kvm_vcpu *vcpu;
	struct kvm_vm *vm;
	struct ucall uc;
	bool guest_done = false;

	vm = test_vm_create(&vcpu);

	test_fw_regs_before_vm_start(vcpu);

	while (!guest_done) {
		vcpu_run(vcpu);

		switch (get_ucall(vcpu, &uc)) {
		case UCALL_SYNC:
			test_guest_stage(&vm, &vcpu);
			break;
		case UCALL_DONE:
			guest_done = true;
			break;
		case UCALL_ABORT:
			REPORT_GUEST_ASSERT(uc);
			break;
		default:
			TEST_FAIL("Unexpected guest exit");
		}
	}

	kvm_vm_free(vm);
}

int main(void)
{
	test_run();
	return 0;
}
