brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · 8e5bd07 Raw
168 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * aarch32_id_regs - Test for ID register behavior on AArch64-only systems4 *5 * Copyright (c) 2022 Google LLC.6 *7 * Test that KVM handles the AArch64 views of the AArch32 ID registers as RAZ8 * and WI from userspace.9 */10 11#include <stdint.h>12 13#include "kvm_util.h"14#include "processor.h"15#include "test_util.h"16#include <linux/bitfield.h>17 18#define BAD_ID_REG_VAL	0x1badc0deul19 20#define GUEST_ASSERT_REG_RAZ(reg)	GUEST_ASSERT_EQ(read_sysreg_s(reg), 0)21 22static void guest_main(void)23{24	GUEST_ASSERT_REG_RAZ(SYS_ID_PFR0_EL1);25	GUEST_ASSERT_REG_RAZ(SYS_ID_PFR1_EL1);26	GUEST_ASSERT_REG_RAZ(SYS_ID_DFR0_EL1);27	GUEST_ASSERT_REG_RAZ(SYS_ID_AFR0_EL1);28	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR0_EL1);29	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR1_EL1);30	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR2_EL1);31	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR3_EL1);32	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR0_EL1);33	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR1_EL1);34	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR2_EL1);35	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR3_EL1);36	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR4_EL1);37	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR5_EL1);38	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR4_EL1);39	GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR6_EL1);40	GUEST_ASSERT_REG_RAZ(SYS_MVFR0_EL1);41	GUEST_ASSERT_REG_RAZ(SYS_MVFR1_EL1);42	GUEST_ASSERT_REG_RAZ(SYS_MVFR2_EL1);43	GUEST_ASSERT_REG_RAZ(sys_reg(3, 0, 0, 3, 3));44	GUEST_ASSERT_REG_RAZ(SYS_ID_PFR2_EL1);45	GUEST_ASSERT_REG_RAZ(SYS_ID_DFR1_EL1);46	GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR5_EL1);47	GUEST_ASSERT_REG_RAZ(sys_reg(3, 0, 0, 3, 7));48 49	GUEST_DONE();50}51 52static void test_guest_raz(struct kvm_vcpu *vcpu)53{54	struct ucall uc;55 56	vcpu_run(vcpu);57 58	switch (get_ucall(vcpu, &uc)) {59	case UCALL_ABORT:60		REPORT_GUEST_ASSERT(uc);61		break;62	case UCALL_DONE:63		break;64	default:65		TEST_FAIL("Unexpected ucall: %lu", uc.cmd);66	}67}68 69static uint64_t raz_wi_reg_ids[] = {70	KVM_ARM64_SYS_REG(SYS_ID_PFR0_EL1),71	KVM_ARM64_SYS_REG(SYS_ID_PFR1_EL1),72	KVM_ARM64_SYS_REG(SYS_ID_DFR0_EL1),73	KVM_ARM64_SYS_REG(SYS_ID_MMFR0_EL1),74	KVM_ARM64_SYS_REG(SYS_ID_MMFR1_EL1),75	KVM_ARM64_SYS_REG(SYS_ID_MMFR2_EL1),76	KVM_ARM64_SYS_REG(SYS_ID_MMFR3_EL1),77	KVM_ARM64_SYS_REG(SYS_ID_ISAR0_EL1),78	KVM_ARM64_SYS_REG(SYS_ID_ISAR1_EL1),79	KVM_ARM64_SYS_REG(SYS_ID_ISAR2_EL1),80	KVM_ARM64_SYS_REG(SYS_ID_ISAR3_EL1),81	KVM_ARM64_SYS_REG(SYS_ID_ISAR4_EL1),82	KVM_ARM64_SYS_REG(SYS_ID_ISAR5_EL1),83	KVM_ARM64_SYS_REG(SYS_ID_MMFR4_EL1),84	KVM_ARM64_SYS_REG(SYS_ID_ISAR6_EL1),85	KVM_ARM64_SYS_REG(SYS_MVFR0_EL1),86	KVM_ARM64_SYS_REG(SYS_MVFR1_EL1),87	KVM_ARM64_SYS_REG(SYS_MVFR2_EL1),88	KVM_ARM64_SYS_REG(SYS_ID_PFR2_EL1),89	KVM_ARM64_SYS_REG(SYS_ID_MMFR5_EL1),90};91 92static void test_user_raz_wi(struct kvm_vcpu *vcpu)93{94	int i;95 96	for (i = 0; i < ARRAY_SIZE(raz_wi_reg_ids); i++) {97		uint64_t reg_id = raz_wi_reg_ids[i];98		uint64_t val;99 100		vcpu_get_reg(vcpu, reg_id, &val);101		TEST_ASSERT_EQ(val, 0);102 103		/*104		 * Expect the ioctl to succeed with no effect on the register105		 * value.106		 */107		vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);108 109		vcpu_get_reg(vcpu, reg_id, &val);110		TEST_ASSERT_EQ(val, 0);111	}112}113 114static uint64_t raz_invariant_reg_ids[] = {115	KVM_ARM64_SYS_REG(SYS_ID_AFR0_EL1),116	KVM_ARM64_SYS_REG(sys_reg(3, 0, 0, 3, 3)),117	KVM_ARM64_SYS_REG(SYS_ID_DFR1_EL1),118	KVM_ARM64_SYS_REG(sys_reg(3, 0, 0, 3, 7)),119};120 121static void test_user_raz_invariant(struct kvm_vcpu *vcpu)122{123	int i, r;124 125	for (i = 0; i < ARRAY_SIZE(raz_invariant_reg_ids); i++) {126		uint64_t reg_id = raz_invariant_reg_ids[i];127		uint64_t val;128 129		vcpu_get_reg(vcpu, reg_id, &val);130		TEST_ASSERT_EQ(val, 0);131 132		r = __vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);133		TEST_ASSERT(r < 0 && errno == EINVAL,134			    "unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);135 136		vcpu_get_reg(vcpu, reg_id, &val);137		TEST_ASSERT_EQ(val, 0);138	}139}140 141 142 143static bool vcpu_aarch64_only(struct kvm_vcpu *vcpu)144{145	uint64_t val, el0;146 147	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &val);148 149	el0 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), val);150	return el0 == ID_AA64PFR0_EL1_ELx_64BIT_ONLY;151}152 153int main(void)154{155	struct kvm_vcpu *vcpu;156	struct kvm_vm *vm;157 158	vm = vm_create_with_one_vcpu(&vcpu, guest_main);159 160	TEST_REQUIRE(vcpu_aarch64_only(vcpu));161 162	test_user_raz_wi(vcpu);163	test_user_raz_invariant(vcpu);164	test_guest_raz(vcpu);165 166	kvm_vm_free(vm);167}168