// SPDX-License-Identifier: GPL-2.0-only
/*
 * vpmu_counter_access - Test vPMU event counter access
 *
 * Copyright (c) 2023 Google LLC.
 *
 * This test checks if the guest can see the same number of the PMU event
 * counters (PMCR_EL0.N) that userspace sets, if the guest can access
 * those counters, and if the guest is prevented from accessing any
 * other counters.
 * It also checks if the userspace accesses to the PMU regsisters honor the
 * PMCR.N value that's set for the guest.
 * This test runs only when KVM_CAP_ARM_PMU_V3 is supported on the host.
 */
#include <kvm_util.h>
#include <processor.h>
#include <test_util.h>
#include <vgic.h>
#include <perf/arm_pmuv3.h>
#include <linux/bitfield.h>

/* The max number of the PMU event counters (excluding the cycle counter) */
#define ARMV8_PMU_MAX_GENERAL_COUNTERS	(ARMV8_PMU_MAX_COUNTERS - 1)

/* The cycle counter bit position that's common among the PMU registers */
#define ARMV8_PMU_CYCLE_IDX		31

struct vpmu_vm {
	struct kvm_vm *vm;
	struct kvm_vcpu *vcpu;
};

static struct vpmu_vm vpmu_vm;

struct pmreg_sets {
	u64 set_reg_id;
	u64 clr_reg_id;
};

#define PMREG_SET(set, clr) {.set_reg_id = set, .clr_reg_id = clr}

static u64 get_pmcr_n(u64 pmcr)
{
	return FIELD_GET(ARMV8_PMU_PMCR_N, pmcr);
}

static u64 get_counters_mask(u64 n)
{
	u64 mask = BIT(ARMV8_PMU_CYCLE_IDX);

	if (n)
		mask |= GENMASK(n - 1, 0);
	return mask;
}

/* Read PMEVTCNTR<n>_EL0 through PMXEVCNTR_EL0 */
static inline unsigned long read_sel_evcntr(int sel)
{
	write_sysreg(sel, pmselr_el0);
	isb();
	return read_sysreg(pmxevcntr_el0);
}

/* Write PMEVTCNTR<n>_EL0 through PMXEVCNTR_EL0 */
static inline void write_sel_evcntr(int sel, unsigned long val)
{
	write_sysreg(sel, pmselr_el0);
	isb();
	write_sysreg(val, pmxevcntr_el0);
	isb();
}

/* Read PMEVTYPER<n>_EL0 through PMXEVTYPER_EL0 */
static inline unsigned long read_sel_evtyper(int sel)
{
	write_sysreg(sel, pmselr_el0);
	isb();
	return read_sysreg(pmxevtyper_el0);
}

/* Write PMEVTYPER<n>_EL0 through PMXEVTYPER_EL0 */
static inline void write_sel_evtyper(int sel, unsigned long val)
{
	write_sysreg(sel, pmselr_el0);
	isb();
	write_sysreg(val, pmxevtyper_el0);
	isb();
}

static void pmu_disable_reset(void)
{
	u64 pmcr = read_sysreg(pmcr_el0);

	/* Reset all counters, disabling them */
	pmcr &= ~ARMV8_PMU_PMCR_E;
	write_sysreg(pmcr | ARMV8_PMU_PMCR_P, pmcr_el0);
	isb();
}

#define RETURN_READ_PMEVCNTRN(n) \
	return read_sysreg(pmevcntr##n##_el0)
static unsigned long read_pmevcntrn(int n)
{
	PMEVN_SWITCH(n, RETURN_READ_PMEVCNTRN);
	return 0;
}

#define WRITE_PMEVCNTRN(n) \
	write_sysreg(val, pmevcntr##n##_el0)
static void write_pmevcntrn(int n, unsigned long val)
{
	PMEVN_SWITCH(n, WRITE_PMEVCNTRN);
	isb();
}

#define READ_PMEVTYPERN(n) \
	return read_sysreg(pmevtyper##n##_el0)
static unsigned long read_pmevtypern(int n)
{
	PMEVN_SWITCH(n, READ_PMEVTYPERN);
	return 0;
}

#define WRITE_PMEVTYPERN(n) \
	write_sysreg(val, pmevtyper##n##_el0)
static void write_pmevtypern(int n, unsigned long val)
{
	PMEVN_SWITCH(n, WRITE_PMEVTYPERN);
	isb();
}

/*
 * The pmc_accessor structure has pointers to PMEV{CNTR,TYPER}<n>_EL0
 * accessors that test cases will use. Each of the accessors will
 * either directly reads/writes PMEV{CNTR,TYPER}<n>_EL0
 * (i.e. {read,write}_pmev{cnt,type}rn()), or reads/writes them through
 * PMXEV{CNTR,TYPER}_EL0 (i.e. {read,write}_sel_ev{cnt,type}r()).
 *
 * This is used to test that combinations of those accessors provide
 * the consistent behavior.
 */
struct pmc_accessor {
	/* A function to be used to read PMEVTCNTR<n>_EL0 */
	unsigned long	(*read_cntr)(int idx);
	/* A function to be used to write PMEVTCNTR<n>_EL0 */
	void		(*write_cntr)(int idx, unsigned long val);
	/* A function to be used to read PMEVTYPER<n>_EL0 */
	unsigned long	(*read_typer)(int idx);
	/* A function to be used to write PMEVTYPER<n>_EL0 */
	void		(*write_typer)(int idx, unsigned long val);
};

struct pmc_accessor pmc_accessors[] = {
	/* test with all direct accesses */
	{ read_pmevcntrn, write_pmevcntrn, read_pmevtypern, write_pmevtypern },
	/* test with all indirect accesses */
	{ read_sel_evcntr, write_sel_evcntr, read_sel_evtyper, write_sel_evtyper },
	/* read with direct accesses, and write with indirect accesses */
	{ read_pmevcntrn, write_sel_evcntr, read_pmevtypern, write_sel_evtyper },
	/* read with indirect accesses, and write with direct accesses */
	{ read_sel_evcntr, write_pmevcntrn, read_sel_evtyper, write_pmevtypern },
};

/*
 * Convert a pointer of pmc_accessor to an index in pmc_accessors[],
 * assuming that the pointer is one of the entries in pmc_accessors[].
 */
#define PMC_ACC_TO_IDX(acc)	(acc - &pmc_accessors[0])

#define GUEST_ASSERT_BITMAP_REG(regname, mask, set_expected)			 \
{										 \
	u64 _tval = read_sysreg(regname);					 \
										 \
	if (set_expected)							 \
		__GUEST_ASSERT((_tval & mask),					 \
				"tval: 0x%lx; mask: 0x%lx; set_expected: %u",	 \
				_tval, mask, set_expected);			 \
	else									 \
		__GUEST_ASSERT(!(_tval & mask),					 \
				"tval: 0x%lx; mask: 0x%lx; set_expected: %u",	 \
				_tval, mask, set_expected);			 \
}

/*
 * Check if @mask bits in {PMCNTEN,PMINTEN,PMOVS}{SET,CLR} registers
 * are set or cleared as specified in @set_expected.
 */
static void check_bitmap_pmu_regs(u64 mask, bool set_expected)
{
	GUEST_ASSERT_BITMAP_REG(pmcntenset_el0, mask, set_expected);
	GUEST_ASSERT_BITMAP_REG(pmcntenclr_el0, mask, set_expected);
	GUEST_ASSERT_BITMAP_REG(pmintenset_el1, mask, set_expected);
	GUEST_ASSERT_BITMAP_REG(pmintenclr_el1, mask, set_expected);
	GUEST_ASSERT_BITMAP_REG(pmovsset_el0, mask, set_expected);
	GUEST_ASSERT_BITMAP_REG(pmovsclr_el0, mask, set_expected);
}

/*
 * Check if the bit in {PMCNTEN,PMINTEN,PMOVS}{SET,CLR} registers corresponding
 * to the specified counter (@pmc_idx) can be read/written as expected.
 * When @set_op is true, it tries to set the bit for the counter in
 * those registers by writing the SET registers (the bit won't be set
 * if the counter is not implemented though).
 * Otherwise, it tries to clear the bits in the registers by writing
 * the CLR registers.
 * Then, it checks if the values indicated in the registers are as expected.
 */
static void test_bitmap_pmu_regs(int pmc_idx, bool set_op)
{
	u64 pmcr_n, test_bit = BIT(pmc_idx);
	bool set_expected = false;

	if (set_op) {
		write_sysreg(test_bit, pmcntenset_el0);
		write_sysreg(test_bit, pmintenset_el1);
		write_sysreg(test_bit, pmovsset_el0);

		/* The bit will be set only if the counter is implemented */
		pmcr_n = get_pmcr_n(read_sysreg(pmcr_el0));
		set_expected = (pmc_idx < pmcr_n) ? true : false;
	} else {
		write_sysreg(test_bit, pmcntenclr_el0);
		write_sysreg(test_bit, pmintenclr_el1);
		write_sysreg(test_bit, pmovsclr_el0);
	}
	check_bitmap_pmu_regs(test_bit, set_expected);
}

/*
 * Tests for reading/writing registers for the (implemented) event counter
 * specified by @pmc_idx.
 */
static void test_access_pmc_regs(struct pmc_accessor *acc, int pmc_idx)
{
	u64 write_data, read_data;

	/* Disable all PMCs and reset all PMCs to zero. */
	pmu_disable_reset();

	/*
	 * Tests for reading/writing {PMCNTEN,PMINTEN,PMOVS}{SET,CLR}_EL1.
	 */

	/* Make sure that the bit in those registers are set to 0 */
	test_bitmap_pmu_regs(pmc_idx, false);
	/* Test if setting the bit in those registers works */
	test_bitmap_pmu_regs(pmc_idx, true);
	/* Test if clearing the bit in those registers works */
	test_bitmap_pmu_regs(pmc_idx, false);

	/*
	 * Tests for reading/writing the event type register.
	 */

	/*
	 * Set the event type register to an arbitrary value just for testing
	 * of reading/writing the register.
	 * Arm ARM says that for the event from 0x0000 to 0x003F,
	 * the value indicated in the PMEVTYPER<n>_EL0.evtCount field is
	 * the value written to the field even when the specified event
	 * is not supported.
	 */
	write_data = (ARMV8_PMU_EXCLUDE_EL1 | ARMV8_PMUV3_PERFCTR_INST_RETIRED);
	acc->write_typer(pmc_idx, write_data);
	read_data = acc->read_typer(pmc_idx);
	__GUEST_ASSERT(read_data == write_data,
		       "pmc_idx: 0x%x; acc_idx: 0x%lx; read_data: 0x%lx; write_data: 0x%lx",
		       pmc_idx, PMC_ACC_TO_IDX(acc), read_data, write_data);

	/*
	 * Tests for reading/writing the event count register.
	 */

	read_data = acc->read_cntr(pmc_idx);

	/* The count value must be 0, as it is disabled and reset */
	__GUEST_ASSERT(read_data == 0,
		       "pmc_idx: 0x%x; acc_idx: 0x%lx; read_data: 0x%lx",
		       pmc_idx, PMC_ACC_TO_IDX(acc), read_data);

	write_data = read_data + pmc_idx + 0x12345;
	acc->write_cntr(pmc_idx, write_data);
	read_data = acc->read_cntr(pmc_idx);
	__GUEST_ASSERT(read_data == write_data,
		       "pmc_idx: 0x%x; acc_idx: 0x%lx; read_data: 0x%lx; write_data: 0x%lx",
		       pmc_idx, PMC_ACC_TO_IDX(acc), read_data, write_data);
}

#define INVALID_EC	(-1ul)
u64 expected_ec = INVALID_EC;

static void guest_sync_handler(struct ex_regs *regs)
{
	u64 esr, ec;

	esr = read_sysreg(esr_el1);
	ec = ESR_ELx_EC(esr);

	__GUEST_ASSERT(expected_ec == ec,
			"PC: 0x%lx; ESR: 0x%lx; EC: 0x%lx; EC expected: 0x%lx",
			regs->pc, esr, ec, expected_ec);

	/* skip the trapping instruction */
	regs->pc += 4;

	/* Use INVALID_EC to indicate an exception occurred */
	expected_ec = INVALID_EC;
}

/*
 * Run the given operation that should trigger an exception with the
 * given exception class. The exception handler (guest_sync_handler)
 * will reset op_end_addr to 0, expected_ec to INVALID_EC, and skip
 * the instruction that trapped.
 */
#define TEST_EXCEPTION(ec, ops)				\
({							\
	GUEST_ASSERT(ec != INVALID_EC);			\
	WRITE_ONCE(expected_ec, ec);			\
	dsb(ish);					\
	ops;						\
	GUEST_ASSERT(expected_ec == INVALID_EC);	\
})

/*
 * Tests for reading/writing registers for the unimplemented event counter
 * specified by @pmc_idx (>= PMCR_EL0.N).
 */
static void test_access_invalid_pmc_regs(struct pmc_accessor *acc, int pmc_idx)
{
	/*
	 * Reading/writing the event count/type registers should cause
	 * an UNDEFINED exception.
	 */
	TEST_EXCEPTION(ESR_ELx_EC_UNKNOWN, acc->read_cntr(pmc_idx));
	TEST_EXCEPTION(ESR_ELx_EC_UNKNOWN, acc->write_cntr(pmc_idx, 0));
	TEST_EXCEPTION(ESR_ELx_EC_UNKNOWN, acc->read_typer(pmc_idx));
	TEST_EXCEPTION(ESR_ELx_EC_UNKNOWN, acc->write_typer(pmc_idx, 0));
	/*
	 * The bit corresponding to the (unimplemented) counter in
	 * {PMCNTEN,PMINTEN,PMOVS}{SET,CLR} registers should be RAZ.
	 */
	test_bitmap_pmu_regs(pmc_idx, 1);
	test_bitmap_pmu_regs(pmc_idx, 0);
}

/*
 * The guest is configured with PMUv3 with @expected_pmcr_n number of
 * event counters.
 * Check if @expected_pmcr_n is consistent with PMCR_EL0.N, and
 * if reading/writing PMU registers for implemented or unimplemented
 * counters works as expected.
 */
static void guest_code(u64 expected_pmcr_n)
{
	u64 pmcr, pmcr_n, unimp_mask;
	int i, pmc;

	__GUEST_ASSERT(expected_pmcr_n <= ARMV8_PMU_MAX_GENERAL_COUNTERS,
			"Expected PMCR.N: 0x%lx; ARMv8 general counters: 0x%x",
			expected_pmcr_n, ARMV8_PMU_MAX_GENERAL_COUNTERS);

	pmcr = read_sysreg(pmcr_el0);
	pmcr_n = get_pmcr_n(pmcr);

	/* Make sure that PMCR_EL0.N indicates the value userspace set */
	__GUEST_ASSERT(pmcr_n == expected_pmcr_n,
			"Expected PMCR.N: 0x%lx, PMCR.N: 0x%lx",
			expected_pmcr_n, pmcr_n);

	/*
	 * Make sure that (RAZ) bits corresponding to unimplemented event
	 * counters in {PMCNTEN,PMINTEN,PMOVS}{SET,CLR} registers are reset
	 * to zero.
	 * (NOTE: bits for implemented event counters are reset to UNKNOWN)
	 */
	unimp_mask = GENMASK_ULL(ARMV8_PMU_MAX_GENERAL_COUNTERS - 1, pmcr_n);
	check_bitmap_pmu_regs(unimp_mask, false);

	/*
	 * Tests for reading/writing PMU registers for implemented counters.
	 * Use each combination of PMEV{CNTR,TYPER}<n>_EL0 accessor functions.
	 */
	for (i = 0; i < ARRAY_SIZE(pmc_accessors); i++) {
		for (pmc = 0; pmc < pmcr_n; pmc++)
			test_access_pmc_regs(&pmc_accessors[i], pmc);
	}

	/*
	 * Tests for reading/writing PMU registers for unimplemented counters.
	 * Use each combination of PMEV{CNTR,TYPER}<n>_EL0 accessor functions.
	 */
	for (i = 0; i < ARRAY_SIZE(pmc_accessors); i++) {
		for (pmc = pmcr_n; pmc < ARMV8_PMU_MAX_GENERAL_COUNTERS; pmc++)
			test_access_invalid_pmc_regs(&pmc_accessors[i], pmc);
	}

	GUEST_DONE();
}

/* Create a VM that has one vCPU with PMUv3 configured. */
static void create_vpmu_vm(void *guest_code)
{
	struct kvm_vcpu_init init;
	u8 pmuver, ec;
	u64 dfr0, irq = 23;
	struct kvm_device_attr irq_attr = {
		.group = KVM_ARM_VCPU_PMU_V3_CTRL,
		.attr = KVM_ARM_VCPU_PMU_V3_IRQ,
		.addr = (u64)&irq,
	};

	/* The test creates the vpmu_vm multiple times. Ensure a clean state */
	memset(&vpmu_vm, 0, sizeof(vpmu_vm));

	vpmu_vm.vm = vm_create(1);
	vm_init_descriptor_tables(vpmu_vm.vm);
	for (ec = 0; ec < ESR_ELx_EC_MAX + 1; ec++) {
		vm_install_sync_handler(vpmu_vm.vm, VECTOR_SYNC_CURRENT, ec,
					guest_sync_handler);
	}

	/* Create vCPU with PMUv3 */
	kvm_get_default_vcpu_target(vpmu_vm.vm, &init);
	init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
	vpmu_vm.vcpu = aarch64_vcpu_add(vpmu_vm.vm, 0, &init, guest_code);
	vcpu_init_descriptor_tables(vpmu_vm.vcpu);

	kvm_arch_vm_finalize_vcpus(vpmu_vm.vm);

	/* Make sure that PMUv3 support is indicated in the ID register */
	dfr0 = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1));
	pmuver = FIELD_GET(ID_AA64DFR0_EL1_PMUVer, dfr0);
	TEST_ASSERT(pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF &&
		    pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP,
		    "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver);

	vcpu_ioctl(vpmu_vm.vcpu, KVM_SET_DEVICE_ATTR, &irq_attr);
}

static void destroy_vpmu_vm(void)
{
	kvm_vm_free(vpmu_vm.vm);
}

static void run_vcpu(struct kvm_vcpu *vcpu, u64 pmcr_n)
{
	struct ucall uc;

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

static void test_create_vpmu_vm_with_nr_counters(unsigned int nr_counters, bool expect_fail)
{
	struct kvm_vcpu *vcpu;
	unsigned int prev;
	int ret;

	create_vpmu_vm(guest_code);
	vcpu = vpmu_vm.vcpu;

	prev = get_pmcr_n(vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0)));

	ret = __vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL,
				     KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS, &nr_counters);

	if (expect_fail)
		TEST_ASSERT(ret && errno == EINVAL,
			    "Setting more PMU counters (%u) than available (%u) unexpectedly succeeded",
			    nr_counters, prev);
	else
		TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret));

	vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, KVM_ARM_VCPU_PMU_V3_INIT, NULL);
}

/*
 * Create a guest with one vCPU, set the PMCR_EL0.N for the vCPU to @pmcr_n,
 * and run the test.
 */
static void run_access_test(u64 pmcr_n)
{
	u64 sp;
	struct kvm_vcpu *vcpu;
	struct kvm_vcpu_init init;

	pr_debug("Test with pmcr_n %lu\n", pmcr_n);

	test_create_vpmu_vm_with_nr_counters(pmcr_n, false);
	vcpu = vpmu_vm.vcpu;

	/* Save the initial sp to restore them later to run the guest again */
	sp = vcpu_get_reg(vcpu, ctxt_reg_alias(vcpu, SYS_SP_EL1));

	run_vcpu(vcpu, pmcr_n);

	/*
	 * Reset and re-initialize the vCPU, and run the guest code again to
	 * check if PMCR_EL0.N is preserved.
	 */
	kvm_get_default_vcpu_target(vpmu_vm.vm, &init);
	init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
	aarch64_vcpu_setup(vcpu, &init);
	vcpu_init_descriptor_tables(vcpu);
	vcpu_set_reg(vcpu, ctxt_reg_alias(vcpu, SYS_SP_EL1), sp);
	vcpu_set_reg(vcpu, ARM64_CORE_REG(regs.pc), (u64)guest_code);

	run_vcpu(vcpu, pmcr_n);

	destroy_vpmu_vm();
}

static struct pmreg_sets validity_check_reg_sets[] = {
	PMREG_SET(SYS_PMCNTENSET_EL0, SYS_PMCNTENCLR_EL0),
	PMREG_SET(SYS_PMINTENSET_EL1, SYS_PMINTENCLR_EL1),
	PMREG_SET(SYS_PMOVSSET_EL0, SYS_PMOVSCLR_EL0),
};

/*
 * Create a VM, and check if KVM handles the userspace accesses of
 * the PMU register sets in @validity_check_reg_sets[] correctly.
 */
static void run_pmregs_validity_test(u64 pmcr_n)
{
	int i;
	struct kvm_vcpu *vcpu;
	u64 set_reg_id, clr_reg_id, reg_val;
	u64 valid_counters_mask, max_counters_mask;

	test_create_vpmu_vm_with_nr_counters(pmcr_n, false);
	vcpu = vpmu_vm.vcpu;

	valid_counters_mask = get_counters_mask(pmcr_n);
	max_counters_mask = get_counters_mask(ARMV8_PMU_MAX_COUNTERS);

	for (i = 0; i < ARRAY_SIZE(validity_check_reg_sets); i++) {
		set_reg_id = validity_check_reg_sets[i].set_reg_id;
		clr_reg_id = validity_check_reg_sets[i].clr_reg_id;

		/*
		 * Test if the 'set' and 'clr' variants of the registers
		 * are initialized based on the number of valid counters.
		 */
		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id));
		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
			    "Initial read of set_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
			    KVM_ARM64_SYS_REG(set_reg_id), reg_val);

		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id));
		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
			    "Initial read of clr_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
			    KVM_ARM64_SYS_REG(clr_reg_id), reg_val);

		/*
		 * Using the 'set' variant, force-set the register to the
		 * max number of possible counters and test if KVM discards
		 * the bits for unimplemented counters as it should.
		 */
		vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), max_counters_mask);

		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id));
		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
			    "Read of set_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
			    KVM_ARM64_SYS_REG(set_reg_id), reg_val);

		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id));
		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
			    "Read of clr_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
			    KVM_ARM64_SYS_REG(clr_reg_id), reg_val);
	}

	destroy_vpmu_vm();
}

/*
 * Create a guest with one vCPU, and attempt to set the PMCR_EL0.N for
 * the vCPU to @pmcr_n, which is larger than the host value.
 * The attempt should fail as @pmcr_n is too big to set for the vCPU.
 */
static void run_error_test(u64 pmcr_n)
{
	pr_debug("Error test with pmcr_n %lu (larger than the host)\n", pmcr_n);

	test_create_vpmu_vm_with_nr_counters(pmcr_n, true);
	destroy_vpmu_vm();
}

/*
 * Return the default number of implemented PMU event counters excluding
 * the cycle counter (i.e. PMCR_EL0.N value) for the guest.
 */
static u64 get_pmcr_n_limit(void)
{
	u64 pmcr;

	create_vpmu_vm(guest_code);
	pmcr = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
	destroy_vpmu_vm();
	return get_pmcr_n(pmcr);
}

static bool kvm_supports_nr_counters_attr(void)
{
	bool supported;

	create_vpmu_vm(NULL);
	supported = !__vcpu_has_device_attr(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL,
					    KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS);
	destroy_vpmu_vm();

	return supported;
}

int main(void)
{
	u64 i, pmcr_n;

	TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_PMU_V3));
	TEST_REQUIRE(kvm_supports_vgic_v3());
	TEST_REQUIRE(kvm_supports_nr_counters_attr());

	pmcr_n = get_pmcr_n_limit();
	for (i = 0; i <= pmcr_n; i++) {
		run_access_test(i);
		run_pmregs_validity_test(i);
	}

	for (i = pmcr_n + 1; i < ARMV8_PMU_MAX_COUNTERS; i++)
		run_error_test(i);

	return 0;
}
