// SPDX-License-Identifier: GPL-2.0-only
/*
 * aarch32_id_regs - Test for ID register behavior on AArch64-only systems
 *
 * Copyright (c) 2022 Google LLC.
 *
 * Test that KVM handles the AArch64 views of the AArch32 ID registers as RAZ
 * and WI from userspace.
 */

#include <stdint.h>

#include "kvm_util.h"
#include "processor.h"
#include "test_util.h"
#include <linux/bitfield.h>

#define BAD_ID_REG_VAL	0x1badc0deul

#define GUEST_ASSERT_REG_RAZ(reg)	GUEST_ASSERT_EQ(read_sysreg_s(reg), 0)

static void guest_main(void)
{
	GUEST_ASSERT_REG_RAZ(SYS_ID_PFR0_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_PFR1_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_DFR0_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_AFR0_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR0_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR1_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR2_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR3_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR0_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR1_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR2_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR3_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR4_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR5_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR4_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR6_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_MVFR0_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_MVFR1_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_MVFR2_EL1);
	GUEST_ASSERT_REG_RAZ(sys_reg(3, 0, 0, 3, 3));
	GUEST_ASSERT_REG_RAZ(SYS_ID_PFR2_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_DFR1_EL1);
	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR5_EL1);
	GUEST_ASSERT_REG_RAZ(sys_reg(3, 0, 0, 3, 7));

	GUEST_DONE();
}

static void test_guest_raz(struct kvm_vcpu *vcpu)
{
	struct ucall uc;

	vcpu_run(vcpu);

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

static u64 raz_wi_reg_ids[] = {
	KVM_ARM64_SYS_REG(SYS_ID_PFR0_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_PFR1_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_DFR0_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_MMFR0_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_MMFR1_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_MMFR2_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_MMFR3_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_ISAR0_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_ISAR1_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_ISAR2_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_ISAR3_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_ISAR4_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_ISAR5_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_MMFR4_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_ISAR6_EL1),
	KVM_ARM64_SYS_REG(SYS_MVFR0_EL1),
	KVM_ARM64_SYS_REG(SYS_MVFR1_EL1),
	KVM_ARM64_SYS_REG(SYS_MVFR2_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_PFR2_EL1),
	KVM_ARM64_SYS_REG(SYS_ID_MMFR5_EL1),
};

static void test_user_raz_wi(struct kvm_vcpu *vcpu)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(raz_wi_reg_ids); i++) {
		u64 reg_id = raz_wi_reg_ids[i];
		u64 val;

		val = vcpu_get_reg(vcpu, reg_id);
		TEST_ASSERT_EQ(val, 0);

		/*
		 * Expect the ioctl to succeed with no effect on the register
		 * value.
		 */
		vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);

		val = vcpu_get_reg(vcpu, reg_id);
		TEST_ASSERT_EQ(val, 0);
	}
}

static u64 raz_invariant_reg_ids[] = {
	KVM_ARM64_SYS_REG(SYS_ID_AFR0_EL1),
	KVM_ARM64_SYS_REG(sys_reg(3, 0, 0, 3, 3)),
	KVM_ARM64_SYS_REG(SYS_ID_DFR1_EL1),
	KVM_ARM64_SYS_REG(sys_reg(3, 0, 0, 3, 7)),
};

static void test_user_raz_invariant(struct kvm_vcpu *vcpu)
{
	int i, r;

	for (i = 0; i < ARRAY_SIZE(raz_invariant_reg_ids); i++) {
		u64 reg_id = raz_invariant_reg_ids[i];
		u64 val;

		val = vcpu_get_reg(vcpu, reg_id);
		TEST_ASSERT_EQ(val, 0);

		r = __vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);
		TEST_ASSERT(r < 0 && errno == EINVAL,
			    "unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);

		val = vcpu_get_reg(vcpu, reg_id);
		TEST_ASSERT_EQ(val, 0);
	}
}



static bool vcpu_aarch64_only(struct kvm_vcpu *vcpu)
{
	u64 val, el0;

	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));

	el0 = FIELD_GET(ID_AA64PFR0_EL1_EL0, val);
	return el0 == ID_AA64PFR0_EL1_EL0_IMP;
}

int main(void)
{
	struct kvm_vcpu *vcpu;
	struct kvm_vm *vm;

	vm = vm_create_with_one_vcpu(&vcpu, guest_main);

	TEST_REQUIRE(vcpu_aarch64_only(vcpu));

	test_user_raz_wi(vcpu);
	test_user_raz_invariant(vcpu);
	test_guest_raz(vcpu);

	kvm_vm_free(vm);
}
