// 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 uint64_t 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++) {
		uint64_t reg_id = raz_wi_reg_ids[i];
		uint64_t val;

		vcpu_get_reg(vcpu, reg_id, &val);
		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);

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

static uint64_t 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++) {
		uint64_t reg_id = raz_invariant_reg_ids[i];
		uint64_t val;

		vcpu_get_reg(vcpu, reg_id, &val);
		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);

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



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

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

	el0 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), val);
	return el0 == ID_AA64PFR0_EL1_ELx_64BIT_ONLY;
}

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);
}
