Path: blob/master/tools/testing/selftests/kvm/arm64/aarch32_id_regs.c
38247 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* aarch32_id_regs - Test for ID register behavior on AArch64-only systems3*4* Copyright (c) 2022 Google LLC.5*6* Test that KVM handles the AArch64 views of the AArch32 ID registers as RAZ7* and WI from userspace.8*/910#include <stdint.h>1112#include "kvm_util.h"13#include "processor.h"14#include "test_util.h"15#include <linux/bitfield.h>1617#define BAD_ID_REG_VAL 0x1badc0deul1819#define GUEST_ASSERT_REG_RAZ(reg) GUEST_ASSERT_EQ(read_sysreg_s(reg), 0)2021static void guest_main(void)22{23GUEST_ASSERT_REG_RAZ(SYS_ID_PFR0_EL1);24GUEST_ASSERT_REG_RAZ(SYS_ID_PFR1_EL1);25GUEST_ASSERT_REG_RAZ(SYS_ID_DFR0_EL1);26GUEST_ASSERT_REG_RAZ(SYS_ID_AFR0_EL1);27GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR0_EL1);28GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR1_EL1);29GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR2_EL1);30GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR3_EL1);31GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR0_EL1);32GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR1_EL1);33GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR2_EL1);34GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR3_EL1);35GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR4_EL1);36GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR5_EL1);37GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR4_EL1);38GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR6_EL1);39GUEST_ASSERT_REG_RAZ(SYS_MVFR0_EL1);40GUEST_ASSERT_REG_RAZ(SYS_MVFR1_EL1);41GUEST_ASSERT_REG_RAZ(SYS_MVFR2_EL1);42GUEST_ASSERT_REG_RAZ(sys_reg(3, 0, 0, 3, 3));43GUEST_ASSERT_REG_RAZ(SYS_ID_PFR2_EL1);44GUEST_ASSERT_REG_RAZ(SYS_ID_DFR1_EL1);45GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR5_EL1);46GUEST_ASSERT_REG_RAZ(sys_reg(3, 0, 0, 3, 7));4748GUEST_DONE();49}5051static void test_guest_raz(struct kvm_vcpu *vcpu)52{53struct ucall uc;5455vcpu_run(vcpu);5657switch (get_ucall(vcpu, &uc)) {58case UCALL_ABORT:59REPORT_GUEST_ASSERT(uc);60break;61case UCALL_DONE:62break;63default:64TEST_FAIL("Unexpected ucall: %lu", uc.cmd);65}66}6768static uint64_t raz_wi_reg_ids[] = {69KVM_ARM64_SYS_REG(SYS_ID_PFR0_EL1),70KVM_ARM64_SYS_REG(SYS_ID_PFR1_EL1),71KVM_ARM64_SYS_REG(SYS_ID_DFR0_EL1),72KVM_ARM64_SYS_REG(SYS_ID_MMFR0_EL1),73KVM_ARM64_SYS_REG(SYS_ID_MMFR1_EL1),74KVM_ARM64_SYS_REG(SYS_ID_MMFR2_EL1),75KVM_ARM64_SYS_REG(SYS_ID_MMFR3_EL1),76KVM_ARM64_SYS_REG(SYS_ID_ISAR0_EL1),77KVM_ARM64_SYS_REG(SYS_ID_ISAR1_EL1),78KVM_ARM64_SYS_REG(SYS_ID_ISAR2_EL1),79KVM_ARM64_SYS_REG(SYS_ID_ISAR3_EL1),80KVM_ARM64_SYS_REG(SYS_ID_ISAR4_EL1),81KVM_ARM64_SYS_REG(SYS_ID_ISAR5_EL1),82KVM_ARM64_SYS_REG(SYS_ID_MMFR4_EL1),83KVM_ARM64_SYS_REG(SYS_ID_ISAR6_EL1),84KVM_ARM64_SYS_REG(SYS_MVFR0_EL1),85KVM_ARM64_SYS_REG(SYS_MVFR1_EL1),86KVM_ARM64_SYS_REG(SYS_MVFR2_EL1),87KVM_ARM64_SYS_REG(SYS_ID_PFR2_EL1),88KVM_ARM64_SYS_REG(SYS_ID_MMFR5_EL1),89};9091static void test_user_raz_wi(struct kvm_vcpu *vcpu)92{93int i;9495for (i = 0; i < ARRAY_SIZE(raz_wi_reg_ids); i++) {96uint64_t reg_id = raz_wi_reg_ids[i];97uint64_t val;9899val = vcpu_get_reg(vcpu, reg_id);100TEST_ASSERT_EQ(val, 0);101102/*103* Expect the ioctl to succeed with no effect on the register104* value.105*/106vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);107108val = vcpu_get_reg(vcpu, reg_id);109TEST_ASSERT_EQ(val, 0);110}111}112113static uint64_t raz_invariant_reg_ids[] = {114KVM_ARM64_SYS_REG(SYS_ID_AFR0_EL1),115KVM_ARM64_SYS_REG(sys_reg(3, 0, 0, 3, 3)),116KVM_ARM64_SYS_REG(SYS_ID_DFR1_EL1),117KVM_ARM64_SYS_REG(sys_reg(3, 0, 0, 3, 7)),118};119120static void test_user_raz_invariant(struct kvm_vcpu *vcpu)121{122int i, r;123124for (i = 0; i < ARRAY_SIZE(raz_invariant_reg_ids); i++) {125uint64_t reg_id = raz_invariant_reg_ids[i];126uint64_t val;127128val = vcpu_get_reg(vcpu, reg_id);129TEST_ASSERT_EQ(val, 0);130131r = __vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);132TEST_ASSERT(r < 0 && errno == EINVAL,133"unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);134135val = vcpu_get_reg(vcpu, reg_id);136TEST_ASSERT_EQ(val, 0);137}138}139140141142static bool vcpu_aarch64_only(struct kvm_vcpu *vcpu)143{144uint64_t val, el0;145146val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));147148el0 = FIELD_GET(ID_AA64PFR0_EL1_EL0, val);149return el0 == ID_AA64PFR0_EL1_EL0_IMP;150}151152int main(void)153{154struct kvm_vcpu *vcpu;155struct kvm_vm *vm;156157vm = vm_create_with_one_vcpu(&vcpu, guest_main);158159TEST_REQUIRE(vcpu_aarch64_only(vcpu));160161test_user_raz_wi(vcpu);162test_user_raz_invariant(vcpu);163test_guest_raz(vcpu);164165kvm_vm_free(vm);166}167168169