Commit a88c7c22 authored by Sebastian Ott's avatar Sebastian Ott Committed by Oliver Upton
Browse files

KVM: selftests: arm64: Test writes to MIDR,REVIDR,AIDR



Assert that MIDR_EL1, REVIDR_EL1, AIDR_EL1 are writable from userspace,
that the changed values are visible to guests, and that they are
preserved across a vCPU reset.

Signed-off-by: default avatarSebastian Ott <sebott@redhat.com>
Link: https://lore.kernel.org/r/20250225005401.679536-6-oliver.upton@linux.dev


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent 3adaee78
Loading
Loading
Loading
Loading
+30 −7
Original line number Diff line number Diff line
@@ -230,6 +230,9 @@ static void guest_code(void)
	GUEST_REG_SYNC(SYS_ID_AA64MMFR2_EL1);
	GUEST_REG_SYNC(SYS_ID_AA64ZFR0_EL1);
	GUEST_REG_SYNC(SYS_CTR_EL0);
	GUEST_REG_SYNC(SYS_MIDR_EL1);
	GUEST_REG_SYNC(SYS_REVIDR_EL1);
	GUEST_REG_SYNC(SYS_AIDR_EL1);

	GUEST_DONE();
}
@@ -609,18 +612,31 @@ static void test_ctr(struct kvm_vcpu *vcpu)
	test_reg_vals[encoding_to_range_idx(SYS_CTR_EL0)] = ctr;
}

static void test_vcpu_ftr_id_regs(struct kvm_vcpu *vcpu)
static void test_id_reg(struct kvm_vcpu *vcpu, u32 id)
{
	u64 val;

	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(id));
	val++;
	vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(id), val);
	test_reg_vals[encoding_to_range_idx(id)] = val;
}

static void test_vcpu_ftr_id_regs(struct kvm_vcpu *vcpu)
{
	test_clidr(vcpu);
	test_ctr(vcpu);

	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1));
	val++;
	vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), val);
	test_id_reg(vcpu, SYS_MPIDR_EL1);
	ksft_test_result_pass("%s\n", __func__);
}

static void test_vcpu_non_ftr_id_regs(struct kvm_vcpu *vcpu)
{
	test_id_reg(vcpu, SYS_MIDR_EL1);
	test_id_reg(vcpu, SYS_REVIDR_EL1);
	test_id_reg(vcpu, SYS_AIDR_EL1);

	test_reg_vals[encoding_to_range_idx(SYS_MPIDR_EL1)] = val;
	ksft_test_result_pass("%s\n", __func__);
}

@@ -647,6 +663,9 @@ static void test_reset_preserves_id_regs(struct kvm_vcpu *vcpu)
	test_assert_id_reg_unchanged(vcpu, SYS_MPIDR_EL1);
	test_assert_id_reg_unchanged(vcpu, SYS_CLIDR_EL1);
	test_assert_id_reg_unchanged(vcpu, SYS_CTR_EL0);
	test_assert_id_reg_unchanged(vcpu, SYS_MIDR_EL1);
	test_assert_id_reg_unchanged(vcpu, SYS_REVIDR_EL1);
	test_assert_id_reg_unchanged(vcpu, SYS_AIDR_EL1);

	ksft_test_result_pass("%s\n", __func__);
}
@@ -660,8 +679,11 @@ int main(void)
	int test_cnt;

	TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES));
	TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_WRITABLE_IMP_ID_REGS));

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
	vm = vm_create(1);
	vm_enable_cap(vm, KVM_CAP_ARM_WRITABLE_IMP_ID_REGS, 0);
	vcpu = vm_vcpu_add(vm, 0, guest_code);

	/* Check for AARCH64 only system */
	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
@@ -675,13 +697,14 @@ int main(void)
		   ARRAY_SIZE(ftr_id_aa64isar2_el1) + ARRAY_SIZE(ftr_id_aa64pfr0_el1) +
		   ARRAY_SIZE(ftr_id_aa64pfr1_el1) + ARRAY_SIZE(ftr_id_aa64mmfr0_el1) +
		   ARRAY_SIZE(ftr_id_aa64mmfr1_el1) + ARRAY_SIZE(ftr_id_aa64mmfr2_el1) +
		   ARRAY_SIZE(ftr_id_aa64zfr0_el1) - ARRAY_SIZE(test_regs) + 2 +
		   ARRAY_SIZE(ftr_id_aa64zfr0_el1) - ARRAY_SIZE(test_regs) + 3 +
		   MPAM_IDREG_TEST;

	ksft_set_plan(test_cnt);

	test_vm_ftr_id_regs(vcpu, aarch64_only);
	test_vcpu_ftr_id_regs(vcpu);
	test_vcpu_non_ftr_id_regs(vcpu);
	test_user_set_mpam_reg(vcpu);

	test_guest_reg_read(vcpu);